Merge /home/vsc/yap

This commit is contained in:
Vítor Santos Costa 2019-05-03 19:09:26 +01:00
commit 937189ab9e
253 changed files with 87345 additions and 4336 deletions

1
.gitignore vendored
View File

@ -215,3 +215,4 @@ cmake/docs/Doxyfile
*.stackdump *.stackdump
*.gz *.gz
.Rproj.user

View File

@ -916,26 +916,24 @@ static int interrupt_dexecute(USES_REGS1) {
static void undef_goal(USES_REGS1) { static void undef_goal(USES_REGS1) {
PredEntry *pe = PredFromDefCode(P); PredEntry *pe = PredFromDefCode(P);
/* avoid trouble with undefined dynamic procedures */ BEGD(d0);
/* I assume they were not locked beforehand */ /* avoid trouble with undefined dynamic procedures */
#if defined(YAPOR) || defined(THREADS) /* I assume they were not locked beforehand */
#if defined(YAPOR) || defined(THREADS)
if (!PP) { if (!PP) {
PELOCK(19, pe); PELOCK(19, pe);
PP = pe; PP = pe;
} }
#endif #endif
BACKUP_MACHINE_REGS(); if (pe->PredFlags & (DynamicPredFlag | LogUpdatePredFlag | MultiFileFlag) ) {
if (pe->PredFlags & (DynamicPredFlag | LogUpdatePredFlag | MultiFileFlag) ) {
#if defined(YAPOR) || defined(THREADS) #if defined(YAPOR) || defined(THREADS)
UNLOCKPE(19, PP); UNLOCKPE(19, PP);
PP = NULL; PP = NULL;
#endif #endif
CalculateStackGap(PASS_REGS1); CalculateStackGap(PASS_REGS1);
P = FAILCODE; P = FAILCODE;
RECOVER_MACHINE_REGS();
return; return;
} }
#if DEBUG
if (UndefCode == NULL || UndefCode->OpcodeOfPred == UNDEF_OPCODE) { if (UndefCode == NULL || UndefCode->OpcodeOfPred == UNDEF_OPCODE) {
fprintf(stderr,"call to undefined Predicates %s ->", IndicatorOfPred(pe)); fprintf(stderr,"call to undefined Predicates %s ->", IndicatorOfPred(pe));
Yap_DebugPlWriteln(ARG1); Yap_DebugPlWriteln(ARG1);
@ -948,28 +946,16 @@ if (pe->PredFlags & (DynamicPredFlag | LogUpdatePredFlag | MultiFileFlag) ) {
#endif #endif
CalculateStackGap(PASS_REGS1); CalculateStackGap(PASS_REGS1);
P = FAILCODE; P = FAILCODE;
RECOVER_MACHINE_REGS();
return; return;
} }
#endif
#if defined(YAPOR) || defined(THREADS) #if defined(YAPOR) || defined(THREADS)
UNLOCKPE(19, PP); UNLOCKPE(19, PP);
PP = NULL; PP = NULL;
#endif #endif
CELL o = AbsPair(HR);
if (pe->ModuleOfPred == PROLOG_MODULE) {
if (CurrentModule == PROLOG_MODULE)
HR[0] = TermProlog;
else
HR[0] = CurrentModule;
} else {
HR[0] = Yap_Module_Name(pe);
}
HR += 2;
if (pe->ArityOfPE == 0) { if (pe->ArityOfPE == 0) {
HR[-1] = MkAtomTerm((Atom)(pe->FunctorOfPred)); d0 = MkAtomTerm((Atom)(pe->FunctorOfPred));
} else { } else {
HR[-1] = AbsAppl(HR); d0 = AbsAppl(HR);
*HR++ = (CELL)pe->FunctorOfPred; *HR++ = (CELL)pe->FunctorOfPred;
CELL *ip=HR; CELL *ip=HR;
UInt imax = pe->ArityOfPE; UInt imax = pe->ArityOfPE;
@ -998,20 +984,30 @@ if (pe->PredFlags & (DynamicPredFlag | LogUpdatePredFlag | MultiFileFlag) ) {
ENDD(d1); ENDD(d1);
} }
} }
ARG1 = o; ARG1 = AbsPair(HR);
ARG2 = MkVarTerm(); HR[1] = d0;
ENDD(d0);
if (pe->ModuleOfPred == PROLOG_MODULE) {
if (CurrentModule == PROLOG_MODULE)
HR[0] = TermProlog;
else
HR[0] = CurrentModule;
} else {
HR[0] = Yap_Module_Name(pe);
}
ARG2 = Yap_getUnknownModule(Yap_GetModuleEntry(HR[0]));
HR += 2;
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) if (Yap_do_low_level_trace)
low_level_trace(enter_pred, UndefCode, XREGS + 1); low_level_trace(enter_pred, UndefCode, XREGS + 1);
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
P = UndefCode->CodeOfPred; P = UndefCode->CodeOfPred;
RECOVER_MACHINE_REGS();
} }
static void spy_goal(USES_REGS1) { static void spy_goal(USES_REGS1) {
PredEntry *pe = PredFromDefCode(P); PredEntry *pe = PredFromDefCode(P);
BACKUP_MACHINE_REGS();
#if defined(YAPOR) || defined(THREADS) #if defined(YAPOR) || defined(THREADS)
if (!PP) { if (!PP) {
PELOCK(14, pe); PELOCK(14, pe);
@ -1031,7 +1027,6 @@ static void spy_goal(USES_REGS1) {
PP = NULL; PP = NULL;
} }
#endif #endif
RECOVER_MACHINE_REGS();
return; return;
} }
} }
@ -1049,7 +1044,6 @@ static void spy_goal(USES_REGS1) {
} }
#endif #endif
Yap_NilError(CALL_COUNTER_UNDERFLOW_EVENT, ""); Yap_NilError(CALL_COUNTER_UNDERFLOW_EVENT, "");
RECOVER_MACHINE_REGS();
return; return;
} }
LOCAL_PredEntriesCounter--; LOCAL_PredEntriesCounter--;
@ -1061,7 +1055,6 @@ static void spy_goal(USES_REGS1) {
} }
#endif #endif
Yap_NilError(PRED_ENTRY_COUNTER_UNDERFLOW_EVENT, ""); Yap_NilError(PRED_ENTRY_COUNTER_UNDERFLOW_EVENT, "");
RECOVER_MACHINE_REGS();
return; return;
} }
if ((pe->PredFlags & (CountPredFlag | ProfiledPredFlag | SpiedPredFlag)) == if ((pe->PredFlags & (CountPredFlag | ProfiledPredFlag | SpiedPredFlag)) ==
@ -1073,7 +1066,6 @@ static void spy_goal(USES_REGS1) {
} }
#endif #endif
P = pe->cs.p_code.TrueCodeOfPred; P = pe->cs.p_code.TrueCodeOfPred;
RECOVER_MACHINE_REGS();
return; return;
} }
} }
@ -1092,7 +1084,6 @@ static void spy_goal(USES_REGS1) {
PP = NULL; PP = NULL;
} }
#endif #endif
RECOVER_MACHINE_REGS();
return; return;
} }
} }
@ -1162,7 +1153,6 @@ static void spy_goal(USES_REGS1) {
low_level_trace(enter_pred, pt0, XREGS + 1); low_level_trace(enter_pred, pt0, XREGS + 1);
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
} }
RECOVER_MACHINE_REGS();
} }
Int Yap_absmi(int inp) { Int Yap_absmi(int inp) {

View File

@ -9,8 +9,8 @@
#endif /* INDENT_CODE */ #endif /* INDENT_CODE */
BOp(Ystop, l); BOp(Ystop, l);
//LOCAL_CBorder = 0; LOCAL_CBorder = 0;
//SET_ASP(YREG, E_CB * sizeof(CELL)); SET_ASP(YREG, E_CB * sizeof(CELL));
/* make sure ASP is initialized */ /* make sure ASP is initialized */
saveregs(); saveregs();
@ -20,13 +20,12 @@
#if BP_FREE #if BP_FREE
P1REG = PCBACKUP; P1REG = PCBACKUP;
#endif #endif
//LOCAL_CBorder = 0; LOCAL_CBorder = 0;
return 1; return 1;
ENDBOp(); ENDBOp();
BOp(Nstop, e); BOp(Nstop, e);
//B= B->cp_b; SET_ASP(YREG, E_CB * sizeof(CELL));
//SET_ASP(YREG, E_CB * sizeof(CELL));
saveregs(); saveregs();
#if PUSH_REGS #if PUSH_REGS
restore_absmi_regs(old_regs); restore_absmi_regs(old_regs);

View File

@ -1,5 +1,4 @@
/************************************************************************* *
/************************************************************************* *
* YAP Prolog * * YAP Prolog *
* Yap Prolog was developed at NCCUP - Universidade do Porto * * Yap Prolog was developed at NCCUP - Universidade do Porto *
* * * *
@ -422,25 +421,8 @@ X_API void *YAP_BlobOfTerm(Term t) {
if (IsVarTerm(t)) if (IsVarTerm(t))
return NULL; return NULL;
if (!IsBigIntTerm(t)) { if (!IsBigIntTerm(t))
if (IsAtomTerm(t)) {
AtomEntry *ae = RepAtom(AtomOfTerm(t));
StaticArrayEntry *pp;
READ_LOCK(ae->ARWLock);
pp = RepStaticArrayProp(ae->PropsOfAE);
while (!EndOfPAEntr(pp) && pp->KindOfPE != ArrayProperty)
pp = RepStaticArrayProp(pp->NextOfPE);
if (EndOfPAEntr(pp) || pp->ValueOfVE.ints == NULL) {
READ_UNLOCK(ae->ARWLock);
return NULL;
} else {
READ_UNLOCK(ae->ARWLock);
return pp->ValueOfVE.ints;
}
}
return NULL; return NULL;
}
src = (MP_INT *)(RepAppl(t) + 2); src = (MP_INT *)(RepAppl(t) + 2);
return (void *)(src + 1); return (void *)(src + 1);
} }
@ -1160,6 +1142,8 @@ X_API Int YAP_Execute(PredEntry *pe, CPredicate exec_code) {
// if (pe->PredFlags & CArgsPredFlag) { // if (pe->PredFlags & CArgsPredFlag) {
// CurrentModule = pe->ModuleOfPred; // CurrentModule = pe->ModuleOfPred;
//} //}
int lvl = push_text_stack();
yhandle_t hdl = Yap_CurrentHandle();
if (pe->PredFlags & SWIEnvPredFlag) { if (pe->PredFlags & SWIEnvPredFlag) {
CPredicateV codev = (CPredicateV)exec_code; CPredicateV codev = (CPredicateV)exec_code;
struct foreign_context ctx; struct foreign_context ctx;
@ -1179,12 +1163,15 @@ X_API Int YAP_Execute(PredEntry *pe, CPredicate exec_code) {
// check for junk: open frames, etc */ // check for junk: open frames, etc */
if (ret) if (ret)
complete_exit(((choiceptr)(LCL0 - OASP)), FALSE, FALSE PASS_REGS); complete_exit(((choiceptr)(LCL0 - OASP)), FALSE, FALSE PASS_REGS);
else else {
complete_fail(((choiceptr)(LCL0 - OASP)), FALSE PASS_REGS); complete_fail(((choiceptr)(LCL0 - OASP)), FALSE PASS_REGS);
}
// CurrentModule = omod; // CurrentModule = omod;
if (!ret) { if (!ret) {
Yap_RaiseException(); Yap_RaiseException();
} }
Yap_RecoverHandles(0, hdl);
pop_text_stack( lvl );
return ret; return ret;
} }
@ -1756,35 +1743,36 @@ static int run_emulator(USES_REGS1) {
X_API bool YAP_EnterGoal(YAP_PredEntryPtr ape, CELL *ptr, YAP_dogoalinfo *dgi) { X_API bool YAP_EnterGoal(YAP_PredEntryPtr ape, CELL *ptr, YAP_dogoalinfo *dgi) {
CACHE_REGS CACHE_REGS
PredEntry *pe = ape; PredEntry *pe = ape;
bool out; bool out;
fprintf(stderr,"EnterGoal: H=%ld ENV=%ld B=%ld TR=%ld P=%p CP=%p, Slots=%ld\n",HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, CP, // fprintf(stderr,"1EnterGoal: H=%d ENV=%p B=%d TR=%d P=%p CP=%p
LOCAL_CurSlot); // Slots=%d\n",HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, CP,
// LOCAL_CurSlot);
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
dgi->lvl = push_text_stack();
LOCAL_ActiveError->errorNo = YAP_NO_ERROR; LOCAL_ActiveError->errorNo = YAP_NO_ERROR;
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
dgi->p = P; dgi->p = P;
dgi->cp = CP; dgi->cp = CP;
dgi->b_top = LCL0 - (CELL *)B; dgi->b0 = LCL0 - (CELL *)B;
dgi->e = LCL0-ENV; dgi->env0 = LCL0 - ENV;
dgi->CurSlot = LOCAL_CurSlot;
// ensure our current ENV receives current P. // ensure our current ENV receives current P.
Yap_PrepGoal(pe->ArityOfPE, nullptr, dgi PASS_REGS); Yap_PrepGoal(pe->ArityOfPE, nullptr, B PASS_REGS);
P = pe->CodeOfPred; P = pe->CodeOfPred;
// __android_log_print(ANDROID_LOG_INFO, "YAP ", "ap=%p %ld %x %x args=%x,%x // __android_log_print(ANDROID_LOG_INFO, "YAP ", "ap=%p %d %x %x args=%x,%x
// slot=%ld", pe, pe->CodeOfPred->opc, FAILCODE, Deref(ARG1), Deref(ARG2), // slot=%d", pe, pe->CodeOfPred->opc, FAILCODE, Deref(ARG1), Deref(ARG2),
// LOCAL_CurSlot); // LOCAL_CurSlot);
dgi->b_entry = LCL0 - (CELL *)B;
dgi->h = HR - H0; dgi->h = HR - H0;
dgi->tr = (CELL *)TR - LCL0; dgi->tr = (CELL *)TR - LCL0;
// HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P11= (LCL0 - (CELL*)B); // fprintf(stderr,"PrepGoal: H=%d ENV=%p B=%d TR=%d P=%p CP=%p Slots=%d\n",
out = Yap_exec_absmi(true, false); // HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, CP, LOCAL_CurSlot);
// fprintf(stderr,"EnterGoal success=%ld: H=%ld ENV=%p B=%ld TR=%ld P=%p CP=%p out = Yap_exec_absmi(true, false);
// Slots=%ld\n", out,HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, CP, // fprintf(stderr,"EnterGoal success=%d: H=%d ENV=%p B=%d TR=%d P=%p CP=%p
// LOCAL_CurSlot); // Slots=%d\n", out,HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, CP,
dgi->b_bottom = (LCL0 - (CELL*)B); // LOCAL_CurSlot);
dgi->e = LCL0 - (CELL *)ENV; dgi->b_exit = LCL0 - (CELL *)B;
dgi->y = LCL0 - (CELL *)YENV;
if (out) { if (out) {
dgi->EndSlot = LOCAL_CurSlot; dgi->EndSlot = LOCAL_CurSlot;
Yap_StartSlots(); Yap_StartSlots();
@ -1792,6 +1780,7 @@ X_API bool YAP_EnterGoal(YAP_PredEntryPtr ape, CELL *ptr, YAP_dogoalinfo *dgi) {
LOCAL_CurSlot = LOCAL_CurSlot =
dgi->CurSlot; // ignore any slots created within the called goal dgi->CurSlot; // ignore any slots created within the called goal
} }
pop_text_stack(dgi->lvl);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return out; return out;
} }
@ -1802,8 +1791,9 @@ X_API bool YAP_RetryGoal(YAP_dogoalinfo *dgi) {
bool out; bool out;
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
myB = (choiceptr)(LCL0 - dgi->b_top); dgi->lvl = push_text_stack();
myB0 = (choiceptr)(LCL0 - dgi->b_bottom); myB = (choiceptr)(LCL0 - dgi->b_exit);
myB0 = (choiceptr)(LCL0 - dgi->b_entry);
CP = myB->cp_cp; CP = myB->cp_cp;
/* sanity check */ /* sanity check */
if (B >= myB0) { if (B >= myB0) {
@ -1813,93 +1803,80 @@ X_API bool YAP_RetryGoal(YAP_dogoalinfo *dgi) {
// get rid of garbage choice-points // get rid of garbage choice-points
B = myB; B = myB;
} }
// fprintf(stderr,"RetryGoal: H=%ld ENV=%p B=%ld TR=%ld P=%p CP=%p Slots=%ld\n", // fprintf(stderr,"RetryGoal: H=%d ENV=%p B=%d TR=%d P=%p CP=%p Slots=%d\n",
// HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, CP, LOCAL_CurSlot); // HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, CP, LOCAL_CurSlot);
P = FAILCODE; P = FAILCODE;
/* make sure we didn't leave live slots when we backtrack */ /* make sure we didn't leave live slots when we backtrack */
ASP = (CELL *)B;
LOCAL_CurSlot = dgi->EndSlot; LOCAL_CurSlot = dgi->EndSlot;
out = Yap_exec_absmi(true, true ); out = Yap_exec_absmi(true, true );
if (out) { if (out) {
dgi->EndSlot = LOCAL_CurSlot; dgi->EndSlot = LOCAL_CurSlot;
dgi->b_bottom = LCL0-CellPtr(myB); dgi->b_exit = LCL0 - (CELL *)B;
} else { } else {
printf("F %ld\n", dgi->CurSlot);
LOCAL_CurSlot = LOCAL_CurSlot =
dgi->CurSlot; // ignore any slots created within the called goal dgi->CurSlot; // ignore any slots created within the called goal
} }
pop_text_stack(dgi->lvl);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return out; return out;
} }
X_API bool YAP_LeaveGoal(bool successful, YAP_dogoalinfo *dgi) { X_API bool YAP_LeaveGoal(bool successful, YAP_dogoalinfo *dgi) {
CACHE_REGS CACHE_REGS
choiceptr myB, handler;
// fprintf(stderr,"LeaveGoal success=%ld: H=%d ENV=%p B=%ldd myB=%ldd TR=%ld // fprintf(stderr,"LeaveGoal success=%d: H=%d ENV=%p B=%ld myB=%ld TR=%d
// P=%p CP=%p Slots=%ld\n", // P=%p CP=%p Slots=%d\n",
// successful,HR-H0,LCL0-ENV,LCL0-(CELL*)B,dgi->b0,(CELL*)TR-LCL0, P, CP, // successful,HR-H0,LCL0-ENV,LCL0-(CELL*)B,dgi->b0,(CELL*)TR-LCL0, P, CP,
// LOCAL_CurSlot); // LOCAL_CurSlot);
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
myB = (choiceptr)(LCL0 - dgi->b_bottom);
if (LOCAL_PrologMode & AsyncIntMode) { dgi->lvl = push_text_stack();
Yap_signal(YAP_FAIL_SIGNAL);
}
handler = B;
while (handler &&
LCL0 - LOCAL_CBorder > (CELL *)handler
//&& handler->cp_ap != NOCODE
&& handler->cp_b != NULL && handler != myB) {
if (handler < myB) {
handler->cp_ap = TRUSTFAILCODE;
}
B = handler;
handler = handler->cp_b;
if (successful) { if (successful) {
choiceptr nB = (choiceptr)(LCL0 - dgi->b_entry);
if (B <= nB) {
B = nB;
}
Yap_TrimTrail(); Yap_TrimTrail();
} else if (!(LOCAL_PrologMode & AsyncIntMode)) { B = B->cp_b;
P = FAILCODE; } else if (LOCAL_PrologMode & AsyncIntMode) {
Yap_exec_absmi(true, YAP_EXEC_ABSMI);
}
}
if (LOCAL_PrologMode & AsyncIntMode) {
Yap_signal(YAP_FAIL_SIGNAL); Yap_signal(YAP_FAIL_SIGNAL);
} }
B = (choiceptr)(LCL0 - dgi->b0);
#ifdef DEPTH_LIMIT
DEPTH = B->cp_depth;
#endif
P = dgi->p; P = dgi->p;
CP = dgi->cp; CP = dgi->cp;
ENV = LCL0-dgi->e; YENV = ENV = LCL0-dgi->env0;
YENV = LCL0-dgi->y; LOCAL_CurSlot =
/* ASP should be set to the top of the local stack when we dgi->CurSlot; // ignore any slots created within the called goal
did the call */ pop_text_stack(dgi->lvl);
SET_ASP(YENV, E_CB * sizeof(CELL));
B = (choiceptr)(LCL0-dgi->b_top)
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
fprintf(stderr,"LeftGoal success=%d: H=%ld ENV=%ld B=%ld TR=%ld P=%p CP=%p, Slots=%ld\n", successful,HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P, // fprintf(stderr," LeftGoal success=%d: H=%d ENV=%p B=%d TR=%d P=%p CP=%p
CP, LOCAL_CurSlot); // Slots=%d\n", successful,HR-H0,LCL0-ENV,LCL0-(CELL*)B,(CELL*)TR-LCL0, P,
// CP, LOCAL_CurSlot);
return TRUE; return TRUE;
} }
X_API Int YAP_RunGoal(Term t) { X_API Int YAP_RunGoal(Term t) {
CACHE_REGS CACHE_REGS
Term out; Term out;
YAP_dogoalinfo gi; yhandle_t cslot = LOCAL_CurSlot;
gi.p = P;
gi.cp = CP;
gi.b_top = LCL0-CellPtr(B);
gi.CurSlot = Yap_CurrentHandle();
gi.y = LCL0-YENV;
gi.e = LCL0-ENV;
yhandle_t cslot = LOCAL_CurSlot;
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
int lvl = push_text_stack();
LOCAL_AllowRestart = FALSE; LOCAL_AllowRestart = FALSE;
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
out = Yap_RunTopGoal(t, &gi, true); out = Yap_RunTopGoal(t, true);
LOCAL_PrologMode = UserCCallMode; LOCAL_PrologMode = UserCCallMode;
// should we catch the exception or pass it through? // should we catch the exception or pass it through?
// We'll pass it through // We'll pass it through
SET_ASP(YENV, E_CB * sizeof(CELL));
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
LOCAL_CurSlot = cslot; LOCAL_CurSlot = cslot;
pop_text_stack(lvl);
return out; return out;
} }
@ -1973,25 +1950,21 @@ X_API CELL *YAP_HeapStoreOpaqueTerm(Term t) {
X_API Int YAP_RunGoalOnce(Term t) { X_API Int YAP_RunGoalOnce(Term t) {
CACHE_REGS CACHE_REGS
Term out; Term out;
YAP_dogoalinfo gi; yamop *old_CP = CP, *old_P = P;
gi.p = P; Int oldPrologMode = LOCAL_PrologMode;
gi.cp = CP;
gi.b_top = LCL0-CellPtr(B);
gi.CurSlot = Yap_CurrentHandle();
gi.y = LCL0-YENV;
gi.e = LCL0-ENV;
Int oldPrologMode = LOCAL_PrologMode;
yhandle_t CSlot; yhandle_t CSlot;
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
int lvl = push_text_stack();
CSlot = Yap_StartSlots(); CSlot = Yap_StartSlots();
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
// Yap_heap_regs->yap_do_low_level_trace=true; // Yap_heap_regs->yap_do_low_level_trace=true;
out = Yap_RunTopGoal(t, &gi, true); out = Yap_RunTopGoal(t, true);
LOCAL_PrologMode = oldPrologMode; LOCAL_PrologMode = oldPrologMode;
// Yap_CloseSlots(CSlot); // Yap_CloseSlots(CSlot);
if (!(oldPrologMode & UserCCallMode)) { if (!(oldPrologMode & UserCCallMode)) {
/* called from top-level */ /* called from top-level */
pop_text_stack( lvl);
LOCAL_AllowRestart = FALSE; LOCAL_AllowRestart = FALSE;
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return out; return out;
@ -2000,33 +1973,40 @@ X_API Int YAP_RunGoalOnce(Term t) {
// We'll pass it through // We'll pass it through
// Yap_RaiseException(); // Yap_RaiseException();
if (out) { if (out) {
choiceptr cut_pt; choiceptr cut_pt, ob;
ob = NULL;
cut_pt = B; cut_pt = B;
B = (choiceptr)(LCL0-gi.b_top); while (cut_pt->cp_ap != NOCODE) {
while (cut_pt->cp_ap != NOCODE && cut_pt < B) {
/* make sure we prune C-choicepoints */ /* make sure we prune C-choicepoints */
cut_pt = cut_pt->cp_b; if (POP_CHOICE_POINT(cut_pt->cp_b)) {
POP_EXECUTE();
}
ob = cut_pt;
cut_pt = cut_pt->cp_b;
} }
B = cut_pt;
Yap_TrimTrail();
} else {
Yap_CloseSlots(CSlot);
}
#ifdef YAPOR #ifdef YAPOR
CUT_prune_to(cut_pt); CUT_prune_to(cut_pt);
#endif #endif
ENV = LCL0-gi.e; if (ob) {
YENV = LCL0-gi.y; B = ob;
B = (choiceptr)(LCL0-gi.b_top); Yap_TrimTrail();
}
B = cut_pt;
} else {
Yap_CloseSlots(CSlot);
}
ASP = B->cp_env;
ENV = (CELL *)ASP[E_E];
B = (choiceptr)ASP[E_CB];
#ifdef DEPTH_LIMIT #ifdef DEPTH_LIMIT
DEPTH = ENV[E_DEPTH]; DEPTH = ASP[E_DEPTH];
#endif #endif
P = gi.p; P = old_P;
CP = gi.cp; CP = old_CP;
SET_ASP(YENV, E_CB * sizeof(CELL));
LOCAL_AllowRestart = FALSE; LOCAL_AllowRestart = FALSE;
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
pop_text_stack( lvl);
return out; return out;
} }
@ -2109,7 +2089,7 @@ X_API void YAP_PruneGoal(YAP_dogoalinfo *gi) {
CACHE_REGS CACHE_REGS
BACKUP_B(); BACKUP_B();
choiceptr myB = (choiceptr)(LCL0 - gi->b_top); choiceptr myB = (choiceptr)(LCL0 - gi->b_entry);
while (B != myB) { while (B != myB) {
/* make sure we prune C-choicepoints */ /* make sure we prune C-choicepoints */
if (POP_CHOICE_POINT(B->cp_b)) { if (POP_CHOICE_POINT(B->cp_b)) {
@ -2166,7 +2146,7 @@ int lvl = push_text_stack();
sno = Yap_OpenStream(tat, "r", MkAtomTerm(Yap_LookupAtom(fname)), sno = Yap_OpenStream(tat, "r", MkAtomTerm(Yap_LookupAtom(fname)),
LOCAL_encoding); LOCAL_encoding);
__android_log_print( __android_log_print(
ANDROID_LOG_INFO, "YAPDroid", "OpenStream got %ld ",sno); ANDROID_LOG_INFO, "YAPDroid", "OpenStream got %d ",sno);
if (sno < 0 || !Yap_ChDir(dirname((char *)d))) { if (sno < 0 || !Yap_ChDir(dirname((char *)d))) {
*full = NULL; *full = NULL;
pop_text_stack(lvl); pop_text_stack(lvl);
@ -2208,7 +2188,7 @@ X_API void YAP_EndConsult(int sno, int *osnop, const char *full) {
if (osnop >= 0) if (osnop >= 0)
Yap_AddAlias(AtomLoopStream, *osnop); Yap_AddAlias(AtomLoopStream, *osnop);
Yap_end_consult(); Yap_end_consult();
__android_log_print(ANDROID_LOG_INFO, "YAPDroid ", " closing %s:%s(%ld), %ld", __android_log_print(ANDROID_LOG_INFO, "YAPDroid ", " closing %s:%s(%d), %d",
CurrentModule == 0 CurrentModule == 0
? "prolog" ? "prolog"
: RepAtom(AtomOfTerm(CurrentModule))->StrOfAE, : RepAtom(AtomOfTerm(CurrentModule))->StrOfAE,
@ -2238,7 +2218,7 @@ X_API Term YAP_ReadFromStream(int sno) {
if (sigsetjmp(signew, 0)) { if (sigsetjmp(signew, 0)) {
Yap_syntax_error(LOCAL_toktide, sno, "ReadFromStream"); Yap_syntax_error(LOCAL_toktide, sno, "ReadFromStream");
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return 0; return 0;
} else { } else {
o = Yap_read_term(sno, TermNil, false); o = Yap_read_term(sno, TermNil, false);
} }
@ -2302,6 +2282,7 @@ X_API char *YAP_WriteBuffer(Term t, char *buf, size_t sze, int flags) {
} else { } else {
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
if (buf == out.val.c) { if (buf == out.val.c) {
pop_text_stack(l);
return buf; return buf;
} else { } else {
if ( strlen(out.val.c ) < sze) { if ( strlen(out.val.c ) < sze) {

440
C/cdmgr.c
View File

@ -202,210 +202,6 @@ restart:
return NULL; return NULL;
} }
/******************************************************************
Mega Clauses
******************************************************************/
#define OrArgAdjust(P)
#define TabEntryAdjust(P)
#define DoubleInCodeAdjust(D)
#define IntegerInCodeAdjust(D)
#define IntegerAdjust(D) (D)
#define PtoPredAdjust(X) (X)
#define PtoOpAdjust(X) (X)
#define PtoLUClauseAdjust(P) (P)
#define PtoLUIndexAdjust(P) (P)
#define XAdjust(X) (X)
#define YAdjust(X) (X)
#define AtomTermAdjust(X) (X)
#define CellPtoHeapAdjust(X) (X)
#define FuncAdjust(X) (X)
#define CodeAddrAdjust(X) (X)
#define CodeComposedTermAdjust(X) (X)
#define ConstantAdjust(X) (X)
#define ArityAdjust(X) (X)
#define OpcodeAdjust(X) (X)
#define ModuleAdjust(X) (X)
#define ExternalFunctionAdjust(X) (X)
#define AdjustSwitchTable(X, Y, Z)
#define DBGroundTermAdjust(X) (X)
#define rehash(A, B, C)
static Term BlobTermInCodeAdjust(Term t) {
CACHE_REGS
#if TAGS_FAST_OPS
return t - LOCAL_ClDiff;
#else
return t + LOCAL_ClDiff;
#endif
}
static Term ConstantTermAdjust(Term t) {
if (IsAtomTerm(t))
return AtomTermAdjust(t);
return t;
}
#include "rclause.h"
#ifdef DEBUG
static UInt total_megaclause, total_released, nof_megaclauses;
#endif
void Yap_BuildMegaClause(PredEntry *ap) {
CACHE_REGS
StaticClause *cl;
UInt sz;
MegaClause *mcl;
yamop *ptr;
size_t required;
UInt has_blobs = 0;
if (ap->PredFlags & (DynamicPredFlag | LogUpdatePredFlag | MegaClausePredFlag
#ifdef TABLING
| TabledPredFlag
#endif /* TABLING */
| UDIPredFlag) ||
ap->cs.p_code.FirstClause == NULL || ap->cs.p_code.NOfClauses < 16) {
return;
}
cl = ClauseCodeToStaticClause(ap->cs.p_code.FirstClause);
sz = cl->ClSize;
while (TRUE) {
if (!(cl->ClFlags & FactMask))
return; /* no mega clause, sorry */
if (cl->ClSize != sz)
return; /* no mega clause, sorry */
if (cl->ClCode == ap->cs.p_code.LastClause)
break;
has_blobs |= (cl->ClFlags & HasBlobsMask);
cl = cl->ClNext;
}
/* ok, we got the chance for a mega clause */
if (has_blobs) {
sz -= sizeof(StaticClause);
} else {
sz -= (UInt)NEXTOP((yamop *)NULL, p) + sizeof(StaticClause);
}
required = sz * ap->cs.p_code.NOfClauses + sizeof(MegaClause) +
(UInt)NEXTOP((yamop *)NULL, l);
while (!(mcl = (MegaClause *)Yap_AllocCodeSpace(required))) {
if (!Yap_growheap(FALSE, required, NULL)) {
/* just fail, the system will keep on going */
return;
}
}
#ifdef DEBUG
total_megaclause += required;
cl = ClauseCodeToStaticClause(ap->cs.p_code.FirstClause);
total_released += ap->cs.p_code.NOfClauses * cl->ClSize;
nof_megaclauses++;
#endif
Yap_ClauseSpace += required;
/* cool, it's our turn to do the conversion */
mcl->ClFlags = MegaMask | has_blobs;
mcl->ClSize = required;
mcl->ClPred = ap;
mcl->ClItemSize = sz;
mcl->ClNext = NULL;
cl = ClauseCodeToStaticClause(ap->cs.p_code.FirstClause);
mcl->ClLine = cl->usc.ClLine;
ptr = mcl->ClCode;
while (TRUE) {
memmove((void *)ptr, (void *)cl->ClCode, sz);
if (has_blobs) {
LOCAL_ClDiff = (char *)(ptr) - (char *)cl->ClCode;
restore_opcodes(ptr, NULL PASS_REGS);
}
ptr = (yamop *)((char *)ptr + sz);
if (cl->ClCode == ap->cs.p_code.LastClause)
break;
cl = cl->ClNext;
}
ptr->opc = Yap_opcode(_Ystop);
cl = ClauseCodeToStaticClause(ap->cs.p_code.FirstClause);
/* recover the space spent on the original clauses */
while (TRUE) {
StaticClause *ncl, *curcl = cl;
ncl = cl->ClNext;
Yap_InformOfRemoval(cl);
Yap_ClauseSpace -= cl->ClSize;
Yap_FreeCodeSpace((ADDR)cl);
if (curcl->ClCode == ap->cs.p_code.LastClause)
break;
cl = ncl;
}
ap->cs.p_code.FirstClause = ap->cs.p_code.LastClause = mcl->ClCode;
ap->PredFlags |= MegaClausePredFlag;
Yap_inform_profiler_of_clause(mcl, (char *)mcl + required, ap, GPROF_MEGA);
}
static void split_megaclause(PredEntry *ap) {
StaticClause *start = NULL, *prev = NULL;
MegaClause *mcl;
yamop *ptr;
UInt ncls = ap->cs.p_code.NOfClauses, i;
mcl = ClauseCodeToMegaClause(ap->cs.p_code.FirstClause);
if (mcl->ClFlags & ExoMask) {
Yap_Error(PERMISSION_ERROR_MODIFY_STATIC_PROCEDURE, Yap_PredicateToIndicator(ap),
"while deleting clause from exo predicate %s/%d\n",
RepAtom(NameOfFunctor(ap->FunctorOfPred))->StrOfAE,
ap->ArityOfPE);
return;
}
RemoveIndexation(ap);
for (i = 0, ptr = mcl->ClCode; i < ncls; i++) {
StaticClause *new = (StaticClause *)Yap_AllocCodeSpace(
sizeof(StaticClause) + mcl->ClItemSize +
(UInt)NEXTOP((yamop *)NULL, p));
if (new == NULL) {
if (!Yap_growheap(FALSE,
(sizeof(StaticClause) + mcl->ClItemSize) * (ncls - i),
NULL)) {
while (start) {
StaticClause *cl = start;
start = cl->ClNext;
Yap_InformOfRemoval(cl);
Yap_ClauseSpace -= cl->ClSize;
Yap_FreeCodeSpace((char *)cl);
}
if (ap->ArityOfPE) {
Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
"while breaking up mega clause for %s/%d\n",
RepAtom(NameOfFunctor(ap->FunctorOfPred))->StrOfAE,
ap->ArityOfPE);
} else {
Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
"while breaking up mega clause for %s\n",
RepAtom((Atom)ap->FunctorOfPred)->StrOfAE);
}
return;
}
break;
}
Yap_ClauseSpace +=
sizeof(StaticClause) + mcl->ClItemSize + (UInt)NEXTOP((yamop *)NULL, p);
new->ClFlags = StaticMask | FactMask;
new->ClSize = mcl->ClItemSize;
new->usc.ClLine = Yap_source_line_no();
new->ClNext = NULL;
memmove((void *)new->ClCode, (void *)ptr, mcl->ClItemSize);
if (prev) {
prev->ClNext = new;
} else {
start = new;
}
ptr = (yamop *)((char *)ptr + mcl->ClItemSize);
prev = new;
}
ap->PredFlags &= ~MegaClausePredFlag;
ap->cs.p_code.FirstClause = start->ClCode;
ap->cs.p_code.LastClause = prev->ClCode;
}
/****************************************************************** /******************************************************************
@ -1763,7 +1559,7 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref)
pflags = p->PredFlags; pflags = p->PredFlags;
/* we are redefining a prolog module predicate */ /* we are redefining a prolog module predicate */
if (pflags & MegaClausePredFlag) { if (pflags & MegaClausePredFlag) {
split_megaclause(p); Yap_split_megaclause(p);
} }
/* The only problem we have now is when we need to throw away /* The only problem we have now is when we need to throw away
Indexing blocks Indexing blocks
@ -1929,11 +1725,11 @@ void Yap_EraseMegaClause(yamop *cl, PredEntry *ap) {
void Yap_EraseStaticClause(StaticClause *cl, PredEntry *ap, Term mod) { void Yap_EraseStaticClause(StaticClause *cl, PredEntry *ap, Term mod) {
/* ok, first I need to find out the parent predicate */ /* ok, first I need to find out the parent predicate */
if (ap->PredFlags & MegaClausePredFlag) {
split_megaclause(ap);
}
if (ap->PredFlags & IndexedPredFlag) if (ap->PredFlags & IndexedPredFlag)
RemoveIndexation(ap); RemoveIndexation(ap);
if (ap->PredFlags & MegaClausePredFlag) {
Yap_split_megaclause(ap);
}
ap->cs.p_code.NOfClauses--; ap->cs.p_code.NOfClauses--;
if (ap->cs.p_code.FirstClause == cl->ClCode) { if (ap->cs.p_code.FirstClause == cl->ClCode) {
/* got rid of first clause */ /* got rid of first clause */
@ -3937,224 +3733,6 @@ p_continue_static_clause(USES_REGS1) {
return fetch_next_static_clause(pe, ipc, Deref(ARG3), ARG4, ARG5, B->cp_ap, return fetch_next_static_clause(pe, ipc, Deref(ARG3), ARG4, ARG5, B->cp_ap,
false); false);
} }
static UInt compute_dbcl_size(arity_t arity) {
UInt sz;
switch (arity) {
case 2:
sz = (UInt)NEXTOP((yamop *)NULL, cc);
break;
case 3:
sz = (UInt)NEXTOP((yamop *)NULL, ccc);
break;
case 4:
sz = (UInt)NEXTOP((yamop *)NULL, cccc);
break;
case 5:
sz = (UInt)NEXTOP((yamop *)NULL, ccccc);
break;
case 6:
sz = (UInt)NEXTOP((yamop *)NULL, cccccc);
break;
default:
sz = arity * (UInt)NEXTOP((yamop *)NULL, xc);
break;
}
return (UInt)NEXTOP((yamop *)sz, p);
}
#define DerefAndCheck(t, V) \
t = Deref(V); \
if (IsVarTerm(t) || !(IsAtomOrIntTerm(t))) \
Yap_Error(TYPE_ERROR_ATOM, t0, "load_db");
static int store_dbcl_size(yamop *pc, arity_t arity, Term t0, PredEntry *pe) {
Term t;
CELL *tp = RepAppl(t0) + 1;
switch (arity) {
case 2:
pc->opc = Yap_opcode(_get_2atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.cc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.cc.c2 = t;
pc = NEXTOP(pc, cc);
break;
case 3:
pc->opc = Yap_opcode(_get_3atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.ccc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.ccc.c2 = t;
DerefAndCheck(t, tp[2]);
pc->y_u.ccc.c3 = t;
pc = NEXTOP(pc, ccc);
break;
case 4:
pc->opc = Yap_opcode(_get_4atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.cccc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.cccc.c2 = t;
DerefAndCheck(t, tp[2]);
pc->y_u.cccc.c3 = t;
DerefAndCheck(t, tp[3]);
pc->y_u.cccc.c4 = t;
pc = NEXTOP(pc, cccc);
break;
case 5:
pc->opc = Yap_opcode(_get_5atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.ccccc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.ccccc.c2 = t;
DerefAndCheck(t, tp[2]);
pc->y_u.ccccc.c3 = t;
DerefAndCheck(t, tp[3]);
pc->y_u.ccccc.c4 = t;
DerefAndCheck(t, tp[4]);
pc->y_u.ccccc.c5 = t;
pc = NEXTOP(pc, ccccc);
break;
case 6:
pc->opc = Yap_opcode(_get_6atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.cccccc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.cccccc.c2 = t;
DerefAndCheck(t, tp[2]);
pc->y_u.cccccc.c3 = t;
DerefAndCheck(t, tp[3]);
pc->y_u.cccccc.c4 = t;
DerefAndCheck(t, tp[4]);
pc->y_u.cccccc.c5 = t;
DerefAndCheck(t, tp[5]);
pc->y_u.cccccc.c6 = t;
pc = NEXTOP(pc, cccccc);
break;
default: {
arity_t i;
for (i = 0; i < arity; i++) {
pc->opc = Yap_opcode(_get_atom);
#if PRECOMPUTE_REGADDRESS
pc->y_u.xc.x = (CELL)(XREGS + (i + 1));
#else
pc->y_u.xc.x = i + 1;
#endif
DerefAndCheck(t, tp[0]);
pc->y_u.xc.c = t;
tp++;
pc = NEXTOP(pc, xc);
}
} break;
}
pc->opc = Yap_opcode(_procceed);
pc->y_u.p.p = pe;
return TRUE;
}
static Int
p_dbload_get_space(USES_REGS1) { /* '$number_of_clauses'(Predicate,M,N) */
Term t = Deref(ARG1);
Term mod = Deref(ARG2);
Term tn = Deref(ARG3);
arity_t arity;
Prop pe;
PredEntry *ap;
UInt sz;
MegaClause *mcl;
yamop *ptr;
UInt ncls;
UInt required;
if (IsVarTerm(mod) || !IsAtomTerm(mod)) {
return (FALSE);
}
if (IsAtomTerm(t)) {
Atom a = AtomOfTerm(t);
arity = 0;
pe = PredPropByAtom(a, mod);
} else if (IsApplTerm(t)) {
register Functor f = FunctorOfTerm(t);
arity = ArityOfFunctor(f);
pe = PredPropByFunc(f, mod);
} else {
return FALSE;
}
if (EndOfPAEntr(pe))
return FALSE;
ap = RepPredProp(pe);
if (ap->PredFlags & (DynamicPredFlag | LogUpdatePredFlag
#ifdef TABLING
| TabledPredFlag
#endif /* TABLING */
)) {
Yap_Error(PERMISSION_ERROR_MODIFY_STATIC_PROCEDURE, Yap_PredicateToIndicator(ap),
"dbload_get_space/4");
return FALSE;
}
if (IsVarTerm(tn) || !IsIntegerTerm(tn)) {
return FALSE;
}
ncls = IntegerOfTerm(tn);
if (ncls <= 1) {
return FALSE;
}
sz = compute_dbcl_size(arity);
required = sz * ncls + sizeof(MegaClause) + (UInt)NEXTOP((yamop *)NULL, l);
#ifdef DEBUG
total_megaclause += required;
nof_megaclauses++;
#endif
while (!(mcl = (MegaClause *)Yap_AllocCodeSpace(required))) {
if (!Yap_growheap(FALSE, required, NULL)) {
/* just fail, the system will keep on going */
return FALSE;
}
}
Yap_ClauseSpace += required;
/* cool, it's our turn to do the conversion */
mcl->ClFlags = MegaMask;
mcl->ClSize = sz * ncls;
mcl->ClPred = ap;
mcl->ClItemSize = sz;
mcl->ClNext = NULL;
ap->cs.p_code.FirstClause = ap->cs.p_code.LastClause = mcl->ClCode;
ap->PredFlags |= (MegaClausePredFlag);
ap->cs.p_code.NOfClauses = ncls;
if (ap->PredFlags & (SpiedPredFlag | CountPredFlag | ProfiledPredFlag)) {
ap->OpcodeOfPred = Yap_opcode(_spy_pred);
} else {
ap->OpcodeOfPred = INDEX_OPCODE;
}
ap->CodeOfPred = ap->cs.p_code.TrueCodeOfPred =
(yamop *)(&(ap->OpcodeOfPred));
ptr = (yamop *)((ADDR)mcl->ClCode + ncls * sz);
ptr->opc = Yap_opcode(_Ystop);
return Yap_unify(ARG4, MkIntegerTerm((Int)mcl));
}
static Int p_dbassert(USES_REGS1) { /* '$number_of_clauses'(Predicate,M,N) */
Term thandle = Deref(ARG2);
Term tn = Deref(ARG3);
PredEntry *pe;
MegaClause *mcl;
Int n;
if (IsVarTerm(thandle) || !IsIntegerTerm(thandle)) {
return FALSE;
}
mcl = (MegaClause *)IntegerOfTerm(thandle);
if (IsVarTerm(tn) || !IsIntegerTerm(tn)) {
return FALSE;
}
n = IntegerOfTerm(tn);
pe = mcl->ClPred;
return store_dbcl_size((yamop *)((ADDR)mcl->ClCode + n * (mcl->ClItemSize)),
pe->ArityOfPE, Deref(ARG1), pe);
}
#define CL_PROP_ERASED 0 #define CL_PROP_ERASED 0
#define CL_PROP_PRED 1 #define CL_PROP_PRED 1
#define CL_PROP_FILE 2 #define CL_PROP_FILE 2
@ -4698,8 +4276,6 @@ static Int init_pred_flag_vals(USES_REGS1) {
void Yap_InitCdMgr(void) { void Yap_InitCdMgr(void) {
CACHE_REGS CACHE_REGS
Term cm = CurrentModule;
Yap_InitCPred("$init_pred_flag_vals", 2, init_pred_flag_vals, SyncPredFlag); Yap_InitCPred("$init_pred_flag_vals", 2, init_pred_flag_vals, SyncPredFlag);
Yap_InitCPred("$start_consult", 3, p_startconsult, Yap_InitCPred("$start_consult", 3, p_startconsult,
SafePredFlag | SyncPredFlag); SafePredFlag | SyncPredFlag);
@ -4792,10 +4368,6 @@ void Yap_InitCdMgr(void) {
Yap_InitCPred("instance_property", 3, instance_property, Yap_InitCPred("instance_property", 3, instance_property,
SafePredFlag | SyncPredFlag); SafePredFlag | SyncPredFlag);
Yap_InitCPred("$fetch_nth_clause", 4, p_nth_instance, SyncPredFlag); Yap_InitCPred("$fetch_nth_clause", 4, p_nth_instance, SyncPredFlag);
CurrentModule = DBLOAD_MODULE;
Yap_InitCPred("dbload_get_space", 4, p_dbload_get_space, 0L);
Yap_InitCPred("dbassert", 3, p_dbassert, 0L);
CurrentModule = cm;
Yap_InitCPred("$predicate_erased_statistics", 5, Yap_InitCPred("$predicate_erased_statistics", 5,
p_predicate_erased_statistics, SyncPredFlag); p_predicate_erased_statistics, SyncPredFlag);
Yap_InitCPred("$including", 2, including, SyncPredFlag | HiddenPredFlag); Yap_InitCPred("$including", 2, including, SyncPredFlag | HiddenPredFlag);
@ -4804,3 +4376,7 @@ void Yap_InitCdMgr(void) {
Yap_InitCPred("$predicate_lu_cps", 4, p_predicate_lu_cps, 0L); Yap_InitCPred("$predicate_lu_cps", 4, p_predicate_lu_cps, 0L);
#endif #endif
} }
void Yap_InitCLoadDB(void) {
}

459
C/dbload.c Normal file
View File

@ -0,0 +1,459 @@
/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* *
**************************************************************************
* *
* File: cdmgr.c *
* comments: Code manager *
* *
* Last rev: $Date: 2008-07-22 23:34:44 $,$Author: vsc $ 8
*************************************************************************/
#include "Yap.h"
#include "YapEval.h"
#include "clause.h"
#include "tracer.h"
#include "yapio.h"
#include <Yatom.h>
#include <assert.h>
#include <heapgc.h>
#include <iopreds.h>
#ifdef DEBUG
static UInt total_megaclause, total_released, nof_megaclauses;
#endif
/******************************************************************
Mega Clauses
******************************************************************/
#define OrArgAdjust(P)
#define TabEntryAdjust(P)
#define DoubleInCodeAdjust(D)
#define IntegerInCodeAdjust(D)
#define IntegerAdjust(D) (D)
#define PtoPredAdjust(X) (X)
#define PtoOpAdjust(X) (X)
#define PtoLUClauseAdjust(P) (P)
#define PtoLUIndexAdjust(P) (P)
#define XAdjust(X) (X)
#define YAdjust(X) (X)
#define AtomTermAdjust(X) (X)
#define CellPtoHeapAdjust(X) (X)
#define FuncAdjust(X) (X)
#define CodeAddrAdjust(X) (X)
#define CodeComposedTermAdjust(X) (X)
#define ConstantAdjust(X) (X)
#define ArityAdjust(X) (X)
#define OpcodeAdjust(X) (X)
#define ModuleAdjust(X) (X)
#define ExternalFunctionAdjust(X) (X)
#define AdjustSwitchTable(X, Y, Z)
#define DBGroundTermAdjust(X) (X)
#define rehash(A, B, C)
static Term BlobTermInCodeAdjust(Term t) {
CACHE_REGS
#if TAGS_FAST_OPS
return t - LOCAL_ClDiff;
#else
return t + LOCAL_ClDiff;
#endif
}
static Term ConstantTermAdjust(Term t) {
if (IsAtomTerm(t))
return AtomTermAdjust(t);
return t;
}
#include "rclause.h"
void Yap_BuildMegaClause(PredEntry *ap) {
CACHE_REGS
StaticClause *cl;
UInt sz;
MegaClause *mcl;
yamop *ptr;
size_t required;
UInt has_blobs = 0;
if (ap->PredFlags & (DynamicPredFlag | LogUpdatePredFlag | MegaClausePredFlag
#ifdef TABLING
| TabledPredFlag
#endif /* TABLING */
| UDIPredFlag) ||
ap->cs.p_code.FirstClause == NULL || ap->cs.p_code.NOfClauses < 16) {
return;
}
cl = ClauseCodeToStaticClause(ap->cs.p_code.FirstClause);
sz = cl->ClSize;
while (TRUE) {
if (!(cl->ClFlags & FactMask))
return; /* no mega clause, sorry */
if (cl->ClSize != sz)
return; /* no mega clause, sorry */
if (cl->ClCode == ap->cs.p_code.LastClause)
break;
has_blobs |= (cl->ClFlags & HasBlobsMask);
cl = cl->ClNext;
}
/* ok, we got the chance for a mega clause */
if (has_blobs) {
sz -= sizeof(StaticClause);
} else {
sz -= (UInt)NEXTOP((yamop *)NULL, p) + sizeof(StaticClause);
}
required = sz * ap->cs.p_code.NOfClauses + sizeof(MegaClause) +
(UInt)NEXTOP((yamop *)NULL, l);
while (!(mcl = (MegaClause *)Yap_AllocCodeSpace(required))) {
if (!Yap_growheap(FALSE, required, NULL)) {
/* just fail, the system will keep on going */
return;
}
}
#ifdef DEBUG
total_megaclause += required;
cl = ClauseCodeToStaticClause(ap->cs.p_code.FirstClause);
total_released += ap->cs.p_code.NOfClauses * cl->ClSize;
nof_megaclauses++;
#endif
Yap_ClauseSpace += required;
/* cool, it's our turn to do the conversion */
mcl->ClFlags = MegaMask | has_blobs;
mcl->ClSize = required;
mcl->ClPred = ap;
mcl->ClItemSize = sz;
mcl->ClNext = NULL;
cl = ClauseCodeToStaticClause(ap->cs.p_code.FirstClause);
mcl->ClLine = cl->usc.ClLine;
ptr = mcl->ClCode;
while (TRUE) {
memmove((void *)ptr, (void *)cl->ClCode, sz);
if (has_blobs) {
LOCAL_ClDiff = (char *)(ptr) - (char *)cl->ClCode;
restore_opcodes(ptr, NULL PASS_REGS);
}
ptr = (yamop *)((char *)ptr + sz);
if (cl->ClCode == ap->cs.p_code.LastClause)
break;
cl = cl->ClNext;
}
ptr->opc = Yap_opcode(_Ystop);
cl = ClauseCodeToStaticClause(ap->cs.p_code.FirstClause);
/* recover the space spent on the original clauses */
while (TRUE) {
StaticClause *ncl, *curcl = cl;
ncl = cl->ClNext;
Yap_InformOfRemoval(cl);
Yap_ClauseSpace -= cl->ClSize;
Yap_FreeCodeSpace((ADDR)cl);
if (curcl->ClCode == ap->cs.p_code.LastClause)
break;
cl = ncl;
}
ap->cs.p_code.FirstClause = ap->cs.p_code.LastClause = mcl->ClCode;
ap->PredFlags |= MegaClausePredFlag;
Yap_inform_profiler_of_clause(mcl, (char *)mcl + required, ap, GPROF_MEGA);
}
void Yap_split_megaclause(PredEntry *ap) {
StaticClause *start = NULL, *prev = NULL;
MegaClause *mcl;
yamop *ptr;
UInt ncls = ap->cs.p_code.NOfClauses, i;
mcl = ClauseCodeToMegaClause(ap->cs.p_code.FirstClause);
if (mcl->ClFlags & ExoMask) {
Yap_Error(PERMISSION_ERROR_MODIFY_STATIC_PROCEDURE, Yap_PredicateToIndicator(ap),
"while deleting clause from exo predicate %s/%d\n",
RepAtom(NameOfFunctor(ap->FunctorOfPred))->StrOfAE,
ap->ArityOfPE);
return;
}
for (i = 0, ptr = mcl->ClCode; i < ncls; i++) {
StaticClause *new = (StaticClause *)Yap_AllocCodeSpace(
sizeof(StaticClause) + mcl->ClItemSize +
(UInt)NEXTOP((yamop *)NULL, p));
if (new == NULL) {
if (!Yap_growheap(FALSE,
(sizeof(StaticClause) + mcl->ClItemSize) * (ncls - i),
NULL)) {
while (start) {
StaticClause *cl = start;
start = cl->ClNext;
Yap_InformOfRemoval(cl);
Yap_ClauseSpace -= cl->ClSize;
Yap_FreeCodeSpace((char *)cl);
}
if (ap->ArityOfPE) {
Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
"while breaking up mega clause for %s/%d\n",
RepAtom(NameOfFunctor(ap->FunctorOfPred))->StrOfAE,
ap->ArityOfPE);
} else {
Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
"while breaking up mega clause for %s\n",
RepAtom((Atom)ap->FunctorOfPred)->StrOfAE);
}
return;
}
break;
}
Yap_ClauseSpace +=
sizeof(StaticClause) + mcl->ClItemSize + (UInt)NEXTOP((yamop *)NULL, p);
new->ClFlags = StaticMask | FactMask;
new->ClSize = mcl->ClItemSize;
new->usc.ClLine = Yap_source_line_no();
new->ClNext = NULL;
memmove((void *)new->ClCode, (void *)ptr, mcl->ClItemSize);
if (prev) {
prev->ClNext = new;
} else {
start = new;
}
ptr = (yamop *)((char *)ptr + mcl->ClItemSize);
prev = new;
}
ap->PredFlags &= ~MegaClausePredFlag;
ap->cs.p_code.FirstClause = start->ClCode;
ap->cs.p_code.LastClause = prev->ClCode;
}
static UInt compute_dbcl_size(arity_t arity) {
UInt sz;
switch (arity) {
case 2:
sz = (UInt)NEXTOP((yamop *)NULL, cc);
break;
case 3:
sz = (UInt)NEXTOP((yamop *)NULL, ccc);
break;
case 4:
sz = (UInt)NEXTOP((yamop *)NULL, cccc);
break;
case 5:
sz = (UInt)NEXTOP((yamop *)NULL, ccccc);
break;
case 6:
sz = (UInt)NEXTOP((yamop *)NULL, cccccc);
break;
default:
sz = arity * (UInt)NEXTOP((yamop *)NULL, xc);
break;
}
return (UInt)NEXTOP((yamop *)sz, p);
}
#define DerefAndCheck(t, V) \
t = Deref(V); \
if (IsVarTerm(t) || !(IsAtomOrIntTerm(t))) \
Yap_Error(TYPE_ERROR_ATOM, t0, "load_db");
static int store_dbcl_size(yamop *pc, arity_t arity, Term t0, PredEntry *pe) {
Term t;
CELL *tp = RepAppl(t0) + 1;
switch (arity) {
case 2:
pc->opc = Yap_opcode(_get_2atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.cc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.cc.c2 = t;
pc = NEXTOP(pc, cc);
break;
case 3:
pc->opc = Yap_opcode(_get_3atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.ccc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.ccc.c2 = t;
DerefAndCheck(t, tp[2]);
pc->y_u.ccc.c3 = t;
pc = NEXTOP(pc, ccc);
break;
case 4:
pc->opc = Yap_opcode(_get_4atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.cccc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.cccc.c2 = t;
DerefAndCheck(t, tp[2]);
pc->y_u.cccc.c3 = t;
DerefAndCheck(t, tp[3]);
pc->y_u.cccc.c4 = t;
pc = NEXTOP(pc, cccc);
break;
case 5:
pc->opc = Yap_opcode(_get_5atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.ccccc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.ccccc.c2 = t;
DerefAndCheck(t, tp[2]);
pc->y_u.ccccc.c3 = t;
DerefAndCheck(t, tp[3]);
pc->y_u.ccccc.c4 = t;
DerefAndCheck(t, tp[4]);
pc->y_u.ccccc.c5 = t;
pc = NEXTOP(pc, ccccc);
break;
case 6:
pc->opc = Yap_opcode(_get_6atoms);
DerefAndCheck(t, tp[0]);
pc->y_u.cccccc.c1 = t;
DerefAndCheck(t, tp[1]);
pc->y_u.cccccc.c2 = t;
DerefAndCheck(t, tp[2]);
pc->y_u.cccccc.c3 = t;
DerefAndCheck(t, tp[3]);
pc->y_u.cccccc.c4 = t;
DerefAndCheck(t, tp[4]);
pc->y_u.cccccc.c5 = t;
DerefAndCheck(t, tp[5]);
pc->y_u.cccccc.c6 = t;
pc = NEXTOP(pc, cccccc);
break;
default: {
arity_t i;
for (i = 0; i < arity; i++) {
pc->opc = Yap_opcode(_get_atom);
#if PRECOMPUTE_REGADDRESS
pc->y_u.xc.x = (CELL)(XREGS + (i + 1));
#else
pc->y_u.xc.x = i + 1;
#endif
DerefAndCheck(t, tp[0]);
pc->y_u.xc.c = t;
tp++;
pc = NEXTOP(pc, xc);
}
} break;
}
pc->opc = Yap_opcode(_procceed);
pc->y_u.p.p = pe;
return TRUE;
}
static Int
p_dbload_get_space(USES_REGS1) { /* '$number_of_clauses'(Predicate,M,N) */
Term t = Deref(ARG1);
Term mod = Deref(ARG2);
Term tn = Deref(ARG3);
arity_t arity;
Prop pe;
PredEntry *ap;
UInt sz;
MegaClause *mcl;
yamop *ptr;
UInt ncls;
UInt required;
if (IsVarTerm(mod) || !IsAtomTerm(mod)) {
return (FALSE);
}
if (IsAtomTerm(t)) {
Atom a = AtomOfTerm(t);
arity = 0;
pe = PredPropByAtom(a, mod);
} else if (IsApplTerm(t)) {
register Functor f = FunctorOfTerm(t);
arity = ArityOfFunctor(f);
pe = PredPropByFunc(f, mod);
} else {
return FALSE;
}
if (EndOfPAEntr(pe))
return FALSE;
ap = RepPredProp(pe);
if (ap->PredFlags & (DynamicPredFlag | LogUpdatePredFlag
#ifdef TABLING
| TabledPredFlag
#endif /* TABLING */
)) {
Yap_Error(PERMISSION_ERROR_MODIFY_STATIC_PROCEDURE, Yap_PredicateToIndicator(ap),
"dbload_get_space/4");
return FALSE;
}
if (IsVarTerm(tn) || !IsIntegerTerm(tn)) {
return FALSE;
}
ncls = IntegerOfTerm(tn);
if (ncls <= 1) {
return FALSE;
}
sz = compute_dbcl_size(arity);
required = sz * ncls + sizeof(MegaClause) + (UInt)NEXTOP((yamop *)NULL, l);
#ifdef DEBUG
total_megaclause += required;
nof_megaclauses++;
#endif
while (!(mcl = (MegaClause *)Yap_AllocCodeSpace(required))) {
if (!Yap_growheap(FALSE, required, NULL)) {
/* just fail, the system will keep on going */
return FALSE;
}
}
Yap_ClauseSpace += required;
/* cool, it's our turn to do the conversion */
mcl->ClFlags = MegaMask;
mcl->ClSize = sz * ncls;
mcl->ClPred = ap;
mcl->ClItemSize = sz;
mcl->ClNext = NULL;
ap->cs.p_code.FirstClause = ap->cs.p_code.LastClause = mcl->ClCode;
ap->PredFlags |= (MegaClausePredFlag);
ap->cs.p_code.NOfClauses = ncls;
if (ap->PredFlags & (SpiedPredFlag | CountPredFlag | ProfiledPredFlag)) {
ap->OpcodeOfPred = Yap_opcode(_spy_pred);
} else {
ap->OpcodeOfPred = INDEX_OPCODE;
}
ap->CodeOfPred = ap->cs.p_code.TrueCodeOfPred =
(yamop *)(&(ap->OpcodeOfPred));
ptr = (yamop *)((ADDR)mcl->ClCode + ncls * sz);
ptr->opc = Yap_opcode(_Ystop);
return Yap_unify(ARG4, MkIntegerTerm((Int)mcl));
}
static Int p_dbassert(USES_REGS1) { /* '$number_of_clauses'(Predicate,M,N) */
Term thandle = Deref(ARG2);
Term tn = Deref(ARG3);
PredEntry *pe;
MegaClause *mcl;
Int n;
if (IsVarTerm(thandle) || !IsIntegerTerm(thandle)) {
return FALSE;
}
mcl = (MegaClause *)IntegerOfTerm(thandle);
if (IsVarTerm(tn) || !IsIntegerTerm(tn)) {
return FALSE;
}
n = IntegerOfTerm(tn);
pe = mcl->ClPred;
return store_dbcl_size((yamop *)((ADDR)mcl->ClCode + n * (mcl->ClItemSize)),
pe->ArityOfPE, Deref(ARG1), pe);
}
void Yap_InitDBLoadPreds(void) {
CACHE_REGS
//CurrentModule = DBLOAD_MODULE;
Yap_InitCPred("$dbload_get_space", 4, p_dbload_get_space, 0L);
Yap_InitCPred("$dbassert", 3, p_dbassert, 0L);
//CurrentModule = cm;
}

View File

@ -1254,7 +1254,7 @@ static Int is_callable(USES_REGS1) {
// Term Context = Deref(ARG2); // Term Context = Deref(ARG2);
while (true) { while (true) {
if (IsVarTerm(G)) { if (IsVarTerm(G)) {
Yap_ThrowError(INSTANTIATION_ERROR, G, NULL); //Yap_ThrowError(INSTANTIATION_ERROR, G, NULL);
return false; return false;
} }
if (IsApplTerm(G)) { if (IsApplTerm(G)) {

167
C/exec.c
View File

@ -801,13 +801,14 @@ static Int execute_in_mod(USES_REGS1) { /* '$execute'(Goal) */
* *
* @method prune_inner_computation * @method prune_inner_computation
*/ */
static void prune_inner_computation(choiceptr parent, YAP_dogoalinfo *gi) { static void prune_inner_computation(choiceptr parent) {
/* code */ /* code */
choiceptr cut_pt; choiceptr cut_pt;
cut_pt = B; cut_pt = B;
while (cut_pt && cut_pt->cp_b while (cut_pt && cut_pt->cp_b < parent) {
&& cut_pt->cp_ap != NOCODE && if (cut_pt->cp_ap == NOCODE)
cut_pt->cp_b <= parent) { break;
cut_pt = cut_pt->cp_b; cut_pt = cut_pt->cp_b;
} }
if (!cut_pt) if (!cut_pt)
@ -818,9 +819,6 @@ static void prune_inner_computation(choiceptr parent, YAP_dogoalinfo *gi) {
B = cut_pt; B = cut_pt;
Yap_TrimTrail(); Yap_TrimTrail();
LOCAL_AllowRestart = FALSE; LOCAL_AllowRestart = FALSE;
P = gi->p;
CP = gi->cp;
ENV = LCL0-gi->e;
B = parent; B = parent;
} }
@ -829,7 +827,7 @@ static void prune_inner_computation(choiceptr parent, YAP_dogoalinfo *gi) {
* after completing a computation. * after completing a computation.
* @method complete_inner_computation * @method complete_inner_computation
*/ */
static void complete_inner_computation(choiceptr old_B, YAP_dogoalinfo *gi) { static void complete_inner_computation(choiceptr old_B) {
choiceptr myB = B; choiceptr myB = B;
if (myB == NULL) { if (myB == NULL) {
return; return;
@ -847,42 +845,30 @@ static void complete_inner_computation(choiceptr old_B, YAP_dogoalinfo *gi) {
return; return;
} }
// restore environment at call... // restore environment at call...
CP = gi->cp; CP = myB->cp_cp;
P = gi->p; ENV = myB->cp_env;
ENV = LCL0-gi->e;
YENV = LCL0-gi->y;
} }
static Int Yap_ignore(Term t, bool fail USES_REGS) { static Int Yap_ignore(Term t, bool fail USES_REGS) {
YAP_dogoalinfo gi; yamop *oP = P, *oCP = CP;
gi.p = P; Int oENV = LCL0 - ENV;
gi.cp = CP; Int oYENV = LCL0 - YENV;
gi.b_top = LCL0-CellPtr(B); Int oB = LCL0 - (CELL *)B;
gi.CurSlot = Yap_CurrentHandle();
gi.y = LCL0-YENV;
gi.e = LCL0-ENV;
// gi. = LCL0-YENV;
yap_error_descriptor_t *ctx = malloc(sizeof(yap_error_descriptor_t)); yap_error_descriptor_t *ctx = malloc(sizeof(yap_error_descriptor_t));
bool newxp = Yap_pushErrorContext(true, ctx); bool newxp = Yap_pushErrorContext(true, ctx);
bool rc = Yap_RunTopGoal(t, &gi, false); bool rc = Yap_RunTopGoal(t, false);
choiceptr B0 = (choiceptr)(LCL0-gi.b_top);
if (!rc) { if (!rc) {
complete_inner_computation(B0, &gi); complete_inner_computation((choiceptr)(LCL0 - oB));
// We'll pass it through // We'll pass it through
} else { } else {
prune_inner_computation(B0, &gi); prune_inner_computation((choiceptr)(LCL0 - oB));
} }
Yap_popErrorContext(newxp, true); Yap_popErrorContext(newxp, true);
ENV = LCL0-gi.e; P = oP;
B = (choiceptr)(LCL0-gi.b_top); CP = oCP;
SET_ASP(ENV, E_CB * sizeof(CELL)); ENV = LCL0 - oENV;
#ifdef DEPTH_LIMIT YENV = LCL0 - oYENV;
DEPTH = ASP[E_DEPTH]; B = (choiceptr)(LCL0 - oB);
#endif
P = gi.p;
CP = gi.cp;
//YENV?
return true; return true;
} }
@ -1012,39 +998,30 @@ static bool watch_retry(Term d0 USES_REGS) {
static Int setup_call_catcher_cleanup(USES_REGS1) { static Int setup_call_catcher_cleanup(USES_REGS1) {
Term Setup = Deref(ARG1); Term Setup = Deref(ARG1);
YAP_dogoalinfo gi; choiceptr B0 = B;
gi.p = P; yamop *oP = P, *oCP = CP;
gi.cp = CP; Int oENV = LCL0 - ENV;
gi.b_top = LCL0-CellPtr(B); Int oYENV = LCL0 - YENV;
gi.CurSlot = Yap_CurrentHandle(); bool rc;
gi.y = LCL0-YENV;
gi.e = LCL0-ENV;
bool rc;
Yap_DisableInterrupts(worker_id); Yap_DisableInterrupts(worker_id);
rc = Yap_RunTopGoal(Setup, &gi, false); rc = Yap_RunTopGoal(Setup, false);
Yap_EnableInterrupts(worker_id); Yap_EnableInterrupts(worker_id);
if (Yap_RaiseException()) { if (Yap_RaiseException()) {
return false; return false;
} }
choiceptr B0=(choiceptr)(LCL0-gi.b_top);
if (!rc) { if (!rc) {
complete_inner_computation(B0, &gi); complete_inner_computation(B0);
// We'll pass it throughs // We'll pass it throughs
return false; return false;
} else { } else {
prune_inner_computation(B0, &gi); prune_inner_computation(B0);
} }
YENV = LCL0-gi.y; P = oP;
ENV = LCL0-gi.e; CP = oCP;
B = (choiceptr)(LCL0-gi.b_top); ENV = LCL0 - oENV;
SET_ASP(YENV, E_CB * sizeof(CELL)); YENV = LCL0 - oYENV;
#ifdef DEPTH_LIMIT
DEPTH = ENV[E_DEPTH];
#endif
P = gi.p;
CP = gi.cp;
return rc; return rc;
} }
@ -1082,8 +1059,6 @@ static Int cleanup_on_exit(USES_REGS1) {
complete_pt[0] = TermExit; complete_pt[0] = TermExit;
} }
Yap_ignore(cleanup, false); Yap_ignore(cleanup, false);
if (B0->cp_ap == NOCODE)
B0->cp_ap = TRUSTFAILCODE;
if (Yap_RaiseException()) { if (Yap_RaiseException()) {
return false; return false;
} }
@ -1618,7 +1593,7 @@ static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) {
ASP = (CELL *)PROTECT_FROZEN_B(B); ASP = (CELL *)PROTECT_FROZEN_B(B);
if (B == NULL || B->cp_b == NULL || if (B == NULL || B->cp_b == NULL ||
(CELL *)(B->cp_b) >= LCL0 - LOCAL_CBorder) { (CELL *)(B->cp_b) > LCL0 - LOCAL_CBorder) {
LOCAL_RestartEnv = sighold; LOCAL_RestartEnv = sighold;
LOCAL_CBorder = OldBorder; LOCAL_CBorder = OldBorder;
pop_text_stack(i + 1); pop_text_stack(i + 1);
@ -1629,26 +1604,25 @@ static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) {
} }
YENV = ASP; YENV = ASP;
YENV[E_CB] = Unsigned(B); YENV[E_CB] = Unsigned(B);
pop_text_stack(i + 1);
out = Yap_absmi(0); out = Yap_absmi(0);
/* make sure we don't leave a FAIL signal hanging around */ /* make sure we don't leave a FAIL signal hanging around */
Yap_get_signal(YAP_FAIL_SIGNAL); Yap_get_signal(YAP_FAIL_SIGNAL);
if (!Yap_has_a_signal()) if (!Yap_has_a_signal())
CalculateStackGap(PASS_REGS1); CalculateStackGap(PASS_REGS1);
LOCAL_CBorder = OldBorder; LOCAL_CBorder = OldBorder;
LOCAL_RestartEnv = sighold; LOCAL_RestartEnv = sighold;
pop_text_stack(i + 1);
return out; return out;
} }
void Yap_PrepGoal(arity_t arity, CELL *pt, YAP_dogoalinfo *gip USES_REGS) { void Yap_PrepGoal(arity_t arity, CELL *pt, choiceptr saved_b USES_REGS) {
/* create an initial pseudo environment so that when garbage /* create an initial pseudo environment so that when garbage
collection is going up in the environment chain it doesn't get collection is going up in the environment chain it doesn't get
confused */ confused */
Yap_ResetException(worker_id); Yap_ResetException(worker_id);
// sl = Yap_InitSlot(t); // sl = Yap_InitSlot(t);
YENV = ASP; YENV = ASP;
YENV[E_CP] = (CELL)CP; YENV[E_CP] = (CELL)YESCODE;
YENV[E_CB] = (CELL)B; YENV[E_CB] = (CELL)B;
YENV[E_E] = (CELL)ENV; YENV[E_E] = (CELL)ENV;
#ifdef TABLING #ifdef TABLING
@ -1668,29 +1642,27 @@ void Yap_PrepGoal(arity_t arity, CELL *pt, YAP_dogoalinfo *gip USES_REGS) {
XREGS[i + 1] = *pt++; XREGS[i + 1] = *pt++;
} }
} }
choiceptr oB = B;
B = (choiceptr)ASP; B = (choiceptr)ASP;
B--; B--;
B->cp_h = HR; B->cp_h = HR;
B->cp_tr = TR; B->cp_tr = TR;
B->cp_cp = YESCODE; B->cp_cp = CP;
B->cp_ap = NOCODE; B->cp_ap = NOCODE;
B->cp_env = ENV; B->cp_env = ENV;
B->cp_b = oB; B->cp_b = saved_b;
#ifdef DEPTH_LIMIT #ifdef DEPTH_LIMIT
B->cp_depth = DEPTH; B->cp_depth = DEPTH;
#endif /* DEPTH_LIMIT */ #endif /* DEPTH_LIMIT */
ASP = (CELL *)B; YENV = ASP = (CELL *)B;
ASP[E_CB] = (CELL)B; YENV[E_CB] = (CELL)B;
HB = HR; HB = HR;
CP = YESCODE; CP = YESCODE;
ASP -= EnvSizeInCells;
gip->b_bottom = LCL0-CellPtr(B);
} }
static bool do_goal(yamop *CodeAdr, int arity, CELL *pt, YAP_dogoalinfo *gi, bool top USES_REGS) { static bool do_goal(yamop *CodeAdr, int arity, CELL *pt, bool top USES_REGS) {
choiceptr saved_b = B;
bool out; bool out;
Yap_PrepGoal(arity, pt, gi PASS_REGS); Yap_PrepGoal(arity, pt, saved_b PASS_REGS);
// CACHE_A1(); // CACHE_A1();
P = (yamop *)CodeAdr; P = (yamop *)CodeAdr;
// S = CellPtr(RepPredProp( // S = CellPtr(RepPredProp(
@ -1762,21 +1734,18 @@ void Yap_fail_all(choiceptr bb USES_REGS) {
} }
bool Yap_execute_pred(PredEntry *ppe, CELL *pt, bool pass_ex USES_REGS) { bool Yap_execute_pred(PredEntry *ppe, CELL *pt, bool pass_ex USES_REGS) {
yamop *saved_p, *saved_cp;
yamop *CodeAdr; yamop *CodeAdr;
bool out; bool out;
YAP_dogoalinfo gi;
gi.p = P; saved_p = P;
gi.cp = CP; saved_cp = CP;
gi.b_top = LCL0-CellPtr(B);
gi.CurSlot = Yap_CurrentHandle();
gi.y = LCL0-YENV;
gi.e = LCL0-ENV;
LOCAL_PrologMode |= TopGoalMode; LOCAL_PrologMode |= TopGoalMode;
PELOCK(81, ppe); PELOCK(81, ppe);
CodeAdr = ppe->CodeOfPred; CodeAdr = ppe->CodeOfPred;
UNLOCK(ppe->PELock); UNLOCK(ppe->PELock);
out = do_goal(CodeAdr, ppe->ArityOfPE, pt, &gi, false PASS_REGS); out = do_goal(CodeAdr, ppe->ArityOfPE, pt, false PASS_REGS);
if (out) { if (out) {
choiceptr cut_B; choiceptr cut_B;
@ -1797,13 +1766,14 @@ bool Yap_execute_pred(PredEntry *ppe, CELL *pt, bool pass_ex USES_REGS) {
#endif #endif
} }
#endif /* TABLING */ #endif /* TABLING */
B = (choiceptr)(LCL0-gi.b_top); B = cut_B;
CP = gi.cp; CP = saved_cp;
P = gi.p; P = saved_p;
ASP = ENV;
#ifdef DEPTH_LIMIT #ifdef DEPTH_LIMIT
DEPTH = ENV[E_DEPTH]; DEPTH = ENV[E_DEPTH];
#endif #endif
ENV = LCL0-gi.e; ENV = (CELL *)(ENV[E_E]);
/* we have failed, and usually we would backtrack to this B, /* we have failed, and usually we would backtrack to this B,
trouble is, we may also have a delayed cut to do */ trouble is, we may also have a delayed cut to do */
if (B != NULL) if (B != NULL)
@ -1822,18 +1792,18 @@ bool Yap_execute_pred(PredEntry *ppe, CELL *pt, bool pass_ex USES_REGS) {
} }
return true; return true;
} else if (out == 0) { } else if (out == 0) {
P = gi.p; P = saved_p;
CP = gi.cp; CP = saved_cp;
HR = B->cp_h; HR = B->cp_h;
#ifdef DEPTH_LIMIT #ifdef DEPTH_LIMIT
DEPTH = B->cp_depth; DEPTH = B->cp_depth;
#endif #endif
/* YENV should be set to the current environment */
YENV = ENV = LCL0-gi.e;
/* ASP should be set to the top of the local stack when we /* ASP should be set to the top of the local stack when we
did the call */ did the call */
SET_ASP(YENV, E_CB * sizeof(CELL)); ASP = B->cp_env;
B =(choiceptr)(LCL0-gi.b_top); /* YENV should be set to the current environment */
YENV = ENV = (CELL *)((B->cp_env)[E_E]);
B = B->cp_b;
SET_BB(B); SET_BB(B);
HB = PROTECT_FROZEN_H(B); HB = PROTECT_FROZEN_H(B);
// should we catch the exception or pass it through? // should we catch the exception or pass it through?
@ -1908,7 +1878,7 @@ void Yap_trust_last(void) {
} }
} }
Term Yap_RunTopGoal(Term t, YAP_dogoalinfo *gip, bool handle_errors) { Term Yap_RunTopGoal(Term t, bool handle_errors) {
CACHE_REGS CACHE_REGS
yamop *CodeAdr; yamop *CodeAdr;
Prop pe; Prop pe;
@ -1917,7 +1887,7 @@ Term Yap_RunTopGoal(Term t, YAP_dogoalinfo *gip, bool handle_errors) {
UInt arity; UInt arity;
Term tmod = CurrentModule; Term tmod = CurrentModule;
Term goal_out = 0; Term goal_out = 0;
LOCAL_PrologMode |= TopGoalMode; LOCAL_PrologMode |= TopGoalMode;
t = Yap_YapStripModule(t, &tmod); t = Yap_YapStripModule(t, &tmod);
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
@ -1987,7 +1957,7 @@ Term Yap_RunTopGoal(Term t, YAP_dogoalinfo *gip, bool handle_errors) {
"unable to boot because of too little Trail space"); "unable to boot because of too little Trail space");
} }
#endif #endif
goal_out = do_goal(CodeAdr, arity, pt, gip, handle_errors PASS_REGS); goal_out = do_goal(CodeAdr, arity, pt, handle_errors PASS_REGS);
return goal_out; return goal_out;
} }
@ -2153,13 +2123,11 @@ bool Yap_Reset(yap_reset_t mode, bool hard) {
Yap_ResetException(worker_id); Yap_ResetException(worker_id);
/* first, backtrack to the root */ /* first, backtrack to the root */
while (B->cp_b) { while (B) {
if (B->cp_ap == NOCODE)
break;
B = B->cp_b;
}
P = FAILCODE; P = FAILCODE;
Yap_exec_absmi(true, mode); Yap_exec_absmi(true, mode);
B = B->cp_b;
}
/* reinitialize the engine */ /* reinitialize the engine */
Yap_InitYaamRegs(worker_id, false); Yap_InitYaamRegs(worker_id, false);
GLOBAL_Initialised = true; GLOBAL_Initialised = true;
@ -2253,7 +2221,6 @@ static Int generate_pred_info(USES_REGS1) {
void Yap_InitYaamRegs(int myworker_id, bool full_reset) { void Yap_InitYaamRegs(int myworker_id, bool full_reset) {
Term h0var; Term h0var;
YAP_dogoalinfo gi;
// getchar(); // getchar();
#if PUSH_REGS #if PUSH_REGS
/* Guarantee that after a longjmp we go back to the original abstract /* Guarantee that after a longjmp we go back to the original abstract
@ -2299,7 +2266,7 @@ void Yap_InitYaamRegs(int myworker_id, bool full_reset) {
REMOTE_AttsMutableList(myworker_id) = Yap_NewTimedVar(h0var); REMOTE_AttsMutableList(myworker_id) = Yap_NewTimedVar(h0var);
#endif #endif
size_t defsz = 128*1024; size_t defsz = 128*1024;
Yap_AllocateDefaultArena(defsz, myworker_id); Yap_AllocateDefaultArena(defsz, myworker_id, NULL);
} else { } else {
HR = Yap_ArenaLimit(REMOTE_GlobalArena(myworker_id)); HR = Yap_ArenaLimit(REMOTE_GlobalArena(myworker_id));
} }
@ -2325,7 +2292,7 @@ void Yap_InitYaamRegs(int myworker_id, bool full_reset) {
PREG_ADDR = NULL; PREG_ADDR = NULL;
#endif #endif
cut_c_initialize(myworker_id); cut_c_initialize(myworker_id);
Yap_PrepGoal(0, NULL, &gi PASS_REGS); Yap_PrepGoal(0, NULL, NULL PASS_REGS);
#ifdef FROZEN_STACKS #ifdef FROZEN_STACKS
H_FZ = HR; H_FZ = HR;
#ifdef YAPOR_SBA #ifdef YAPOR_SBA

View File

@ -78,7 +78,7 @@ assert/1 or recorda/3.
+ The value lives on the Prolog (global) stack. This implies + The value lives on the Prolog (global) stack. This implies
that lookup time is independent from the size of the term. that lookup time is independent from the size of the term.
This is particulary interesting for large data structures This is particulary interesting for large data structures
such as parsed XML documents or the CHR global constraint qqqsuch as parsed XML documents or the CHR global constraint
store. store.
They support both global assignment using nb_setval/2 and They support both global assignment using nb_setval/2 and
@ -139,6 +139,26 @@ threads that are created <em>after</em> the registration.
#define HEAP_ARENA 2 #define HEAP_ARENA 2
#define HEAP_START 3 #define HEAP_START 3
/// A cell_space is a short code region, where we want bindings to proceed locally.
/// It is used in copy_term,,,,,,,,,,,,,,,,,,,,,,,
///
typedef struct cell_space {
struct cell_space *parent; //`
CELL *oASP, *oH, *oHB;
} cell_space_t;
INLINE_ONLY void enter_cell_space(cell_space_t *cs) {
cs->oH = HR;
cs->oHB = HB;
cs->oASP = ASP;
}
INLINE_ONLY void exit_cell_space(cell_space_t *cs) {
HR = cs->oH;
HB = cs->oHB;
ASP = cs->oASP;
}
#define MIN_ARENA_SIZE (1048L) #define MIN_ARENA_SIZE (1048L)
#define MAX_ARENA_SIZE (2048 * 16) #define MAX_ARENA_SIZE (2048 * 16)
@ -186,33 +206,37 @@ static Term CreateNewArena(CELL *ptr, UInt size) {
return t; return t;
} }
static Term NewArena(UInt size, int wid, UInt arity, CELL *where) { static Term NewArena(UInt size, int wid, UInt arity, CELL *where, struct cell_space *cellSpace) {
Term t; Term t;
UInt new_size; UInt new_size;
WORKER_REGS(wid) WORKER_REGS(wid)
exit_cell_space(cellSpace);
if (where == NULL || where == HR) { // make sure we have enough room
while (HR + size > ASP - 1024) { while (HR + size > ASP - MIN_ARENA_SIZE) {
if (!Yap_gcl(size * sizeof(CELL), arity, ENV, P)) { if (!Yap_gcl(size * sizeof(CELL), arity, ENV, P)) {
Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
return TermNil; return TermNil;
} }
} }
if (where == NULL || where == HR) {
t = CreateNewArena(HR, size); t = CreateNewArena(HR, size);
HR += size; HR += size;
new_size = size;
} else { } else {
if ((new_size = Yap_InsertInGlobal(where, size * sizeof(CELL))) == 0) { if ((new_size = Yap_InsertInGlobal(where, size * sizeof(CELL))) == 0) {
Yap_Error(RESOURCE_ERROR_STACK, TermNil, Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil,
"No Stack Space for Non-Backtrackable terms"); "No Stack Space for Non-Backtrackable terms");
return TermNil; return TermNil;
} }
size = new_size / sizeof(CELL); size = new_size / sizeof(CELL);
t = CreateNewArena(where, size); t = CreateNewArena(where, size);
} }
enter_cell_space(cellSpace);
return t; return t;
} }
static Int p_allocate_arena(USES_REGS1) { static Int p_allocate_arena(USES_REGS1) {
cell_space_t cspace;
Term t = Deref(ARG1); Term t = Deref(ARG1);
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
Yap_Error(INSTANTIATION_ERROR, t, "allocate_arena"); Yap_Error(INSTANTIATION_ERROR, t, "allocate_arena");
@ -221,15 +245,21 @@ static Int p_allocate_arena(USES_REGS1) {
Yap_Error(TYPE_ERROR_INTEGER, t, "allocate_arena"); Yap_Error(TYPE_ERROR_INTEGER, t, "allocate_arena");
return FALSE; return FALSE;
} }
return Yap_unify(ARG2, NewArena(IntegerOfTerm(t), worker_id, 1, NULL)); enter_cell_space(&cspace);
return Yap_unify(ARG2, NewArena(IntegerOfTerm(t), worker_id, 1, NULL, &cspace));
} }
static Int p_default_arena_size(USES_REGS1) { static Int p_default_arena_size(USES_REGS1) {
return Yap_unify(ARG1, MkIntegerTerm(ArenaSz(LOCAL_GlobalArena))); return Yap_unify(ARG1, MkIntegerTerm(ArenaSz(LOCAL_GlobalArena)));
} }
void Yap_AllocateDefaultArena(size_t gsize, int wid) { void Yap_AllocateDefaultArena(size_t gsize, int wid, void *cs) {
REMOTE_GlobalArena(wid) = NewArena(gsize, wid, 2, NULL); cell_space_t ics;
if (cs == NULL) {
enter_cell_space(&ics);
cs = &ics;
}
REMOTE_GlobalArena(wid) = NewArena(gsize, wid, 2, NULL, cs);
} }
static void adjust_cps(UInt size USES_REGS) { static void adjust_cps(UInt size USES_REGS) {
@ -241,8 +271,9 @@ static void adjust_cps(UInt size USES_REGS) {
} }
} }
static int GrowArena(Term arena, CELL *pt, size_t old_size, size_t size, static Term GrowArena(Term arena, CELL *pt, size_t old_size, size_t size,
UInt arity USES_REGS) { UInt arity, cell_space_t *cspace USES_REGS) {
size_t sz;
LOCAL_ArenaOverflows++; LOCAL_ArenaOverflows++;
if (size == 0) { if (size == 0) {
if (old_size < 128 * 1024) { if (old_size < 128 * 1024) {
@ -251,59 +282,51 @@ static int GrowArena(Term arena, CELL *pt, size_t old_size, size_t size,
size = old_size + 128 * 1024; size = old_size + 128 * 1024;
} }
} }
if (size < 4096) { if (size < 4*MIN_ARENA_SIZE) {
size = 4096; size = 4*MIN_ARENA_SIZE;
} }
if (pt == HR) { while (HR + size > ASP - MIN_ARENA_SIZE) {
if (HR + size > ASP - 1024) {
XREGS[arity + 1] = arena; XREGS[arity + 1] = arena;
if (!Yap_gcl(size * sizeof(CELL), arity + 1, ENV, gc_P(P, CP))) { if (!Yap_gcl(size * sizeof(CELL), arity + 1, ENV, gc_P(P, CP))) {
Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
return FALSE; return false;
} }
arena = XREGS[arity + 1]; arena = XREGS[arity + 1];
/* we don't know if the GC added junk on top of the global */ adjust_cps(size PASS_REGS);
pt = ArenaLimit(arena);
return GrowArena(arena, pt, old_size, size, arity PASS_REGS);
}
adjust_cps(size PASS_REGS);
HR += size;
} else {
XREGS[arity + 1] = arena;
/* try to recover some room */
Yap_gcl(size * sizeof(CELL), arity + 1, ENV, gc_P(P, CP));
arena = XREGS[arity + 1];
pt = ArenaLimit(arena);
if ((size = Yap_InsertInGlobal(pt, size * sizeof(CELL))) == 0) {
return FALSE;
}
size = size / sizeof(CELL);
arena = XREGS[arity + 1];
} }
CreateNewArena(ArenaPt(arena), size + old_size); pt = ArenaLimit(arena);
return TRUE; sz = old_size + size;
if (pt == HR) {
HR += size;
HR[ - 1] = EndSpecials;
} else {
if ((sz = Yap_InsertInGlobal(pt, size * sizeof(CELL))) == 0) {
return FALSE;
}
pt[size-1] = EndSpecials;
}
arena = XREGS[arity + 1];
MP_INT *dst = (MP_INT *)(RepAppl(arena) + 2);
dst->_mp_alloc+= size;
arena = XREGS[arity + 1];
return sz;
} }
CELL *Yap_GetFromArena(Term *arenap, UInt cells, UInt arity) { CELL *Yap_GetFromArena(Term *arenap, UInt cells, UInt arity) {
CACHE_REGS CACHE_REGS
restart : {
Term arena = *arenap; Term arena = *arenap;
CELL *max = ArenaLimit(arena); CELL *max = ArenaLimit(arena);
CELL *base = ArenaPt(arena); CELL *base = ArenaPt(arena);
CELL *newH; CELL *newH;
UInt old_sz = ArenaSz(arena), new_size; UInt old_sz = ArenaSz(arena), new_size;
while(true) {
if (IN_BETWEEN(base, HR, max)) { if (IN_BETWEEN(base, HR, max)) {
base = HR; base = HR;
HR += cells; HR += cells;
return base; return base;
} }
if (base + cells > max - 1024) { if (base + cells > ASP - 1024) {
if (!GrowArena(arena, max, old_sz, old_sz + sizeof(CELL) * 1024, continue;
arity PASS_REGS))
return NULL;
goto restart;
} }
newH = base + cells; newH = base + cells;
@ -313,17 +336,15 @@ restart : {
} }
} }
static void CloseArena(CELL *oldH, CELL *oldHB, CELL *oldASP, Term *oldArenaP, static void CloseArena(cell_space_t *region, Term *oldArenaP,
UInt old_size USES_REGS) { UInt old_size USES_REGS) {
UInt new_size; UInt new_size;
if (HR == oldH) if (HR == region->oH)
return; return;
new_size = old_size - (HR - RepAppl(*oldArenaP)); new_size = old_size - (HR - RepAppl(*oldArenaP));
*oldArenaP = CreateNewArena(HR, new_size); *oldArenaP = CreateNewArena(HR, new_size);
HR = oldH; exit_cell_space( region );
HB = oldHB;
ASP = oldASP;
} }
static inline void clean_dirty_tr(tr_fr_ptr TR0 USES_REGS) { static inline void clean_dirty_tr(tr_fr_ptr TR0 USES_REGS) {
@ -474,7 +495,9 @@ loop:
HR += ap2[1] + 3; HR += ap2[1] + 3;
break; break;
default: { default: {
/* big int */
/* big int */
UInt sz = (sizeof(MP_INT) + 3 * CellSize + UInt sz = (sizeof(MP_INT) + 3 * CellSize +
((MP_INT *)(ap2 + 2))->_mp_alloc * sizeof(mp_limb_t)) / ((MP_INT *)(ap2 + 2))->_mp_alloc * sizeof(mp_limb_t)) /
CellSize, CellSize,
@ -482,7 +505,7 @@ loop:
if (HR > ASP - (MIN_ARENA_SIZE + sz)) { if (HR > ASP - (MIN_ARENA_SIZE + sz)) {
goto overflow; goto overflow;
} }
*ptf++ = AbsAppl(HR); *ptf++ = AbsAppl(HR);
HR[0] = (CELL)f; HR[0] = (CELL)f;
for (i = 1; i < sz; i++) { for (i = 1; i < sz; i++) {
@ -494,6 +517,7 @@ loop:
continue; continue;
} }
*ptf = AbsAppl(HR); *ptf = AbsAppl(HR);
ptf++; ptf++;
/* store the terms to visit */ /* store the terms to visit */
#ifdef RATIONAL_TREES #ifdef RATIONAL_TREES
@ -643,14 +667,14 @@ static Term CopyTermToArena(Term t, Term arena, bool share, bool copy_att_vars,
UInt arity, Term *newarena, UInt arity, Term *newarena,
size_t min_grow USES_REGS) { size_t min_grow USES_REGS) {
size_t old_size = ArenaSz(arena); size_t old_size = ArenaSz(arena);
CELL *oldH = HR; cell_space_t cspace;
CELL *oldHB = HB;
CELL *oldASP = ASP;
int res = 0; int res = 0;
Term tn; Term tn;
int restarts = 0;
restart: restart:
t = Deref(t); t = Deref(t);
enter_cell_space( & cspace);
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
ASP = ArenaLimit(arena); ASP = ArenaLimit(arena);
HR = HB = ArenaPt(arena); HR = HB = ArenaPt(arena);
@ -664,12 +688,12 @@ restart:
if ((res = copy_complex_term(Hi - 2, Hi - 1, share, copy_att_vars, Hi, if ((res = copy_complex_term(Hi - 2, Hi - 1, share, copy_att_vars, Hi,
Hi PASS_REGS)) < 0) Hi PASS_REGS)) < 0)
goto error_handler; goto error_handler;
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cspace, newarena, old_size PASS_REGS);
return Hi[0]; return Hi[0];
} }
#endif #endif
if (share && VarOfTerm(t) > ArenaPt(arena)) { if (share && VarOfTerm(t) > ArenaPt(arena)) {
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cspace, newarena, old_size PASS_REGS);
return t; return t;
} }
tn = MkVarTerm(); tn = MkVarTerm();
@ -677,7 +701,7 @@ restart:
res = -1; res = -1;
goto error_handler; goto error_handler;
} }
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cspace, newarena, old_size PASS_REGS);
return tn; return tn;
} else if (IsAtomOrIntTerm(t)) { } else if (IsAtomOrIntTerm(t)) {
return t; return t;
@ -699,7 +723,7 @@ restart:
Hi PASS_REGS)) < 0) { Hi PASS_REGS)) < 0) {
goto error_handler; goto error_handler;
} }
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cspace, newarena, old_size PASS_REGS);
return tf; return tf;
} else { } else {
Functor f; Functor f;
@ -720,7 +744,7 @@ restart:
if (IsExtensionFunctor(f)) { if (IsExtensionFunctor(f)) {
switch ((CELL)f) { switch ((CELL)f) {
case (CELL) FunctorDBRef: case (CELL) FunctorDBRef:
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cspace, newarena, old_size PASS_REGS);
return t; return t;
case (CELL) FunctorLongInt: case (CELL) FunctorLongInt:
if (HR > ASP - (MIN_ARENA_SIZE + 3)) { if (HR > ASP - (MIN_ARENA_SIZE + 3)) {
@ -779,25 +803,25 @@ restart:
goto error_handler; goto error_handler;
} }
} }
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cspace, newarena, old_size PASS_REGS);
return tf; return tf;
} }
error_handler: error_handler:
HR = HB; HR = HB;
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cspace, newarena, old_size PASS_REGS);
XREGS[arity + 1] = t; XREGS[arity + 1] = t;
XREGS[arity + 2] = arena; XREGS[arity + 2] = arena;
XREGS[arity + 3] = (CELL)newarena; XREGS[arity + 3] = (CELL)newarena;
{ {
CELL *old_top = ArenaLimit(*newarena); CELL *old_top = ArenaLimit(*newarena);
ASP = oldASP; exit_cell_space(&cspace);
HR = oldH;
HB = oldHB;
switch (res) { switch (res) {
case -1: case -1:
if (arena == LOCAL_GlobalArena) if (arena == LOCAL_GlobalArena)
LOCAL_GlobalArenaOverflows++; LOCAL_GlobalArenaOverflows++;
if (!GrowArena(arena, old_top, old_size, min_grow, arity + 3 PASS_REGS)) { restarts++;
min_grow += (restarts < 16 ? 16*1024*restarts*restarts : 128*1024*1024);
if ((arena=GrowArena(arena, old_top, old_size, min_grow, arity + 3, &cspace PASS_REGS))==0) {
Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
return 0L; return 0L;
} }
@ -807,9 +831,7 @@ error_handler:
} }
} }
oldH = HR; enter_cell_space(&cspace);
oldHB = HB;
oldASP = ASP;
newarena = (CELL *)XREGS[arity + 3]; newarena = (CELL *)XREGS[arity + 3];
arena = Deref(XREGS[arity + 2]); arena = Deref(XREGS[arity + 2]);
t = XREGS[arity + 1]; t = XREGS[arity + 1];
@ -819,10 +841,9 @@ error_handler:
static Term CreateTermInArena(Term arena, Atom Na, UInt Nar, UInt arity, static Term CreateTermInArena(Term arena, Atom Na, UInt Nar, UInt arity,
Term *newarena, Term init USES_REGS) { Term *newarena, Term init USES_REGS) {
cell_space_t cells;
UInt old_size = ArenaSz(arena); UInt old_size = ArenaSz(arena);
CELL *oldH = HR; enter_cell_space(&cells);
CELL *oldHB = HB;
CELL *oldASP = ASP;
Term tf; Term tf;
CELL *HB0; CELL *HB0;
Functor f = Yap_MkFunctor(Na, Nar); Functor f = Yap_MkFunctor(Na, Nar);
@ -838,26 +859,20 @@ restart:
if (HR > ASP - MIN_ARENA_SIZE) { if (HR > ASP - MIN_ARENA_SIZE) {
/* overflow */ /* overflow */
HR = HB; HR = HB;
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cells, newarena, old_size PASS_REGS);
XREGS[arity + 1] = arena; XREGS[arity + 1] = arena;
XREGS[arity + 2] = (CELL)newarena; XREGS[arity + 2] = (CELL)newarena;
{ {
CELL *old_top = ArenaLimit(*newarena); CELL *old_top = ArenaLimit(*newarena);
ASP = oldASP;
HR = oldH;
HB = oldHB;
if (arena == LOCAL_GlobalArena) if (arena == LOCAL_GlobalArena)
LOCAL_GlobalArenaOverflows++; LOCAL_GlobalArenaOverflows++;
if (!GrowArena(arena, old_top, old_size, Nar * sizeof(CELL), if ((arena=GrowArena(arena, old_top, old_size, Nar * sizeof(CELL),
arity + 2 PASS_REGS)) { arity + 2, &cells PASS_REGS))==0) {
Yap_Error(RESOURCE_ERROR_STACK, TermNil, Yap_Error(RESOURCE_ERROR_STACK, TermNil,
"while creating large global term"); "while creating large global term");
return 0L; return 0L;
} }
} }
oldH = HR;
oldHB = HB;
oldASP = ASP;
newarena = (CELL *)XREGS[arity + 2]; newarena = (CELL *)XREGS[arity + 2];
arena = Deref(XREGS[arity + 1]); arena = Deref(XREGS[arity + 1]);
old_size = ArenaSz(arena); old_size = ArenaSz(arena);
@ -872,7 +887,7 @@ restart:
HB0[i] = init; HB0[i] = init;
} }
} }
CloseArena(oldH, oldHB, oldASP, newarena, old_size PASS_REGS); CloseArena(&cells, newarena, old_size PASS_REGS);
return tf; return tf;
} }
@ -1534,9 +1549,9 @@ static Int p_nb_create2(USES_REGS1) {
static Int nb_queue(UInt arena_sz USES_REGS) { static Int nb_queue(UInt arena_sz USES_REGS) {
cell_space_t cspace;
Term queue_arena, queue, ar[QUEUE_FUNCTOR_ARITY], *nar; Term queue_arena, queue, ar[QUEUE_FUNCTOR_ARITY], *nar;
Term t = Deref(ARG1); Term t = Deref(ARG1);
LOCAL_DepthArenas++; LOCAL_DepthArenas++;
if (!IsVarTerm(t)) { if (!IsVarTerm(t)) {
if (!IsApplTerm(t)) { if (!IsApplTerm(t)) {
@ -1549,15 +1564,16 @@ static Int nb_queue(UInt arena_sz USES_REGS) {
queue = Yap_MkApplTerm(FunctorNBQueue, QUEUE_FUNCTOR_ARITY, ar); queue = Yap_MkApplTerm(FunctorNBQueue, QUEUE_FUNCTOR_ARITY, ar);
if (!Yap_unify(queue, ARG1)) if (!Yap_unify(queue, ARG1))
return FALSE; return FALSE;
if (arena_sz < 4 * 1024) if (arena_sz < 32 * 1024)
arena_sz = 4 * 1024; arena_sz = 32 * 1024;
queue_arena = NewArena(arena_sz, worker_id, 1, NULL); enter_cell_space(&cspace);
queue_arena = NewArena(arena_sz, worker_id, 1, NULL, &cspace);
if (queue_arena == 0L) { if (queue_arena == 0L) {
return FALSE; return FALSE;
} }
nar = RepAppl(Deref(ARG1)) + 1; nar = RepAppl(Deref(ARG1)) + 1;
nar[QUEUE_ARENA] = queue_arena; nar[QUEUE_ARENA] = queue_arena;
return TRUE; return true;
} }
static Int p_nb_queue(USES_REGS1) { static Int p_nb_queue(USES_REGS1) {
@ -1656,7 +1672,7 @@ static Int p_nb_queue_close(USES_REGS1) {
} }
static Int p_nb_queue_enqueue(USES_REGS1) { static Int p_nb_queue_enqueue(USES_REGS1) {
CELL *qd = GetQueue(ARG1, "enqueue"), *oldH, *oldHB; CELL *qd = GetQueue(ARG1, "enqueue");
UInt old_sz; UInt old_sz;
Term arena, qsize, to; Term arena, qsize, to;
UInt min_size; UInt min_size;
@ -1664,8 +1680,10 @@ static Int p_nb_queue_enqueue(USES_REGS1) {
if (!qd) if (!qd)
return FALSE; return FALSE;
arena = GetQueueArena(qd, "enqueue"); arena = GetQueueArena(qd, "enqueue");
if (arena == 0L) if (arena == 0L) {
return FALSE; return FALSE;
}
if (IsPairTerm(qd[QUEUE_HEAD])) { if (IsPairTerm(qd[QUEUE_HEAD])) {
min_size = ArenaPt(arena) - RepPair(qd[QUEUE_HEAD]); min_size = ArenaPt(arena) - RepPair(qd[QUEUE_HEAD]);
} else { } else {
@ -1675,37 +1693,15 @@ static Int p_nb_queue_enqueue(USES_REGS1) {
min_size PASS_REGS); min_size PASS_REGS);
if (to == 0L) if (to == 0L)
return FALSE; return FALSE;
cell_space_t cspace;
qd = GetQueue(ARG1, "enqueue"); qd = GetQueue(ARG1, "enqueue");
arena = GetQueueArena(qd, "enqueue"); arena = GetQueueArena(qd, "enqueue");
/* garbage collection ? */ /* garbage collection ? */
oldH = HR; enter_cell_space(&cspace);
oldHB = HB;
HR = HB = ArenaPt(arena); HR = HB = ArenaPt(arena);
old_sz = ArenaSz(arena); old_sz = ArenaSz(arena);
qsize = IntegerOfTerm(qd[QUEUE_SIZE]); qsize = IntegerOfTerm(qd[QUEUE_SIZE]);
while (old_sz < MIN_ARENA_SIZE) {
UInt gsiz = HR - RepPair(qd[QUEUE_HEAD]);
HR = oldH;
HB = oldHB;
if (gsiz > 1024 * 1024) {
gsiz = 1024 * 1024;
} else if (gsiz < 1024) {
gsiz = 1024;
}
ARG3 = to;
/* fprintf(stderr,"growing %ld cells\n",(unsigned long int)gsiz);*/
if (!GrowArena(arena, ArenaLimit(arena), old_sz, gsiz, 3 PASS_REGS)) {
Yap_Error(RESOURCE_ERROR_STACK, arena, LOCAL_ErrorMessage);
return 0L;
}
to = ARG3;
qd = RepAppl(Deref(ARG1)) + 1;
arena = GetQueueArena(qd, "enqueue");
oldH = HR;
oldHB = HB;
HR = HB = ArenaPt(arena);
old_sz = ArenaSz(arena);
}
qd[QUEUE_SIZE] = Global_MkIntegerTerm(qsize + 1); qd[QUEUE_SIZE] = Global_MkIntegerTerm(qsize + 1);
if (qsize == 0) { if (qsize == 0) {
qd[QUEUE_HEAD] = AbsPair(HR); qd[QUEUE_HEAD] = AbsPair(HR);
@ -1716,7 +1712,7 @@ static Int p_nb_queue_enqueue(USES_REGS1) {
RESET_VARIABLE(HR); RESET_VARIABLE(HR);
qd[QUEUE_TAIL] = (CELL)HR; qd[QUEUE_TAIL] = (CELL)HR;
HR++; HR++;
CloseArena(oldH, oldHB, ASP, qd + QUEUE_ARENA, old_sz PASS_REGS); CloseArena(&cspace, qd + QUEUE_ARENA, old_sz PASS_REGS);
return TRUE; return TRUE;
} }
@ -1724,7 +1720,7 @@ static Int p_nb_queue_dequeue(USES_REGS1) {
CELL *qd = GetQueue(ARG1, "dequeue"); CELL *qd = GetQueue(ARG1, "dequeue");
UInt old_sz, qsz; UInt old_sz, qsz;
Term arena, out; Term arena, out;
CELL *oldH, *oldHB; cell_space_t cspace;
if (!qd) if (!qd)
return FALSE; return FALSE;
@ -1738,10 +1734,9 @@ static Int p_nb_queue_dequeue(USES_REGS1) {
out = HeadOfTerm(qd[QUEUE_HEAD]); out = HeadOfTerm(qd[QUEUE_HEAD]);
qd[QUEUE_HEAD] = TailOfTerm(qd[QUEUE_HEAD]); qd[QUEUE_HEAD] = TailOfTerm(qd[QUEUE_HEAD]);
/* garbage collection ? */ /* garbage collection ? */
oldH = HR; enter_cell_space(&cspace);
oldHB = HB;
qd[QUEUE_SIZE] = Global_MkIntegerTerm(qsz - 1); qd[QUEUE_SIZE] = Global_MkIntegerTerm(qsz - 1);
CloseArena(oldH, oldHB, ASP, &arena, old_sz PASS_REGS); CloseArena(&cspace, &arena, old_sz PASS_REGS);
return Yap_unify(out, ARG2); return Yap_unify(out, ARG2);
} }
@ -1838,6 +1833,7 @@ static Term MkZeroApplTerm(Functor f, UInt sz USES_REGS) {
static Int p_nb_heap(USES_REGS1) { static Int p_nb_heap(USES_REGS1) {
Term heap_arena, heap, *ar, *nar; Term heap_arena, heap, *ar, *nar;
UInt hsize; UInt hsize;
cell_space_t cspace;
Term tsize = Deref(ARG1); Term tsize = Deref(ARG1);
UInt arena_sz = (ASP-HR) / 16; UInt arena_sz = (ASP-HR) / 16;
@ -1868,7 +1864,7 @@ static Int p_nb_heap(USES_REGS1) {
ar[HEAP_MAX] = tsize; ar[HEAP_MAX] = tsize;
if (arena_sz < 1024) if (arena_sz < 1024)
arena_sz = 1024; arena_sz = 1024;
heap_arena = NewArena(arena_sz, worker_id, 1, NULL); heap_arena = NewArena(arena_sz, worker_id, 1, NULL, &cspace);
if (heap_arena == 0L) { if (heap_arena == 0L) {
return FALSE; return FALSE;
} }
@ -1946,10 +1942,11 @@ static void DelHeapRoot(CELL *pt, UInt sz) {
} }
static Int p_nb_heap_add_to_heap(USES_REGS1) { static Int p_nb_heap_add_to_heap(USES_REGS1) {
CELL *qd = GetHeap(ARG1, "add_to_heap"), *oldH, *oldHB, *pt; CELL *qd = GetHeap(ARG1, "add_to_heap"), *pt;
UInt hsize, hmsize, old_sz; UInt hsize, hmsize, old_sz;
Term arena, to, key; Term arena, to, key;
UInt mingrow; UInt mingrow;
cell_space_t cspace;
if (!qd) if (!qd)
return FALSE; return FALSE;
@ -1971,7 +1968,8 @@ restart:
"No Stack Space for Non-Backtrackable terms"); "No Stack Space for Non-Backtrackable terms");
return FALSE; return FALSE;
} }
extra_size = extra_size / (2 * sizeof(CELL)); enter_cell_space(&cspace);
extra_size = extra_size / (2 * sizeof(CELL));
qd = GetHeap(ARG1, "add_to_heap"); qd = GetHeap(ARG1, "add_to_heap");
hmsize += extra_size; hmsize += extra_size;
if (!qd) if (!qd)
@ -1986,11 +1984,9 @@ restart:
} }
arena = qd[HEAP_ARENA]; arena = qd[HEAP_ARENA];
old_sz = ArenaSz(arena); old_sz = ArenaSz(arena);
oldH = HR;
oldHB = HB;
HR = HB = ArenaPt(arena); HR = HB = ArenaPt(arena);
qd[HEAP_MAX] = Global_MkIntegerTerm(hmsize); qd[HEAP_MAX] = Global_MkIntegerTerm(hmsize);
CloseArena(oldH, oldHB, ASP, qd + HEAP_ARENA, old_sz PASS_REGS); CloseArena(&cspace, qd + HEAP_ARENA, old_sz PASS_REGS);
goto restart; goto restart;
} }
arena = qd[HEAP_ARENA]; arena = qd[HEAP_ARENA];
@ -2010,30 +2006,25 @@ restart:
qd = GetHeap(ARG1, "add_to_heap"); qd = GetHeap(ARG1, "add_to_heap");
arena = qd[HEAP_ARENA]; arena = qd[HEAP_ARENA];
/* garbage collection ? */ /* garbage collection ? */
oldH = HR; enter_cell_space(&cspace);
oldHB = HB;
HR = HB = ArenaPt(arena); HR = HB = ArenaPt(arena);
old_sz = ArenaSz(arena); old_sz = ArenaSz(arena);
while (old_sz < MIN_ARENA_SIZE) { while (old_sz < MIN_ARENA_SIZE) {
UInt gsiz = hsize * 2; UInt gsiz = hsize * 2;
HR = oldH;
HB = oldHB;
if (gsiz > 1024 * 1024) { if (gsiz > 1024 * 1024) {
gsiz = 1024 * 1024; gsiz = 1024 * 1024;
} else if (gsiz < 1024) { } else if (gsiz < 1024) {
gsiz = 1024; gsiz = 1024;
} }
ARG3 = to; ARG3 = to;
if (!GrowArena(arena, ArenaLimit(arena), old_sz, gsiz, 3 PASS_REGS)) { if ((arena=GrowArena(arena, ArenaLimit(arena), old_sz, gsiz, 3, &cspace PASS_REGS))==0) {
Yap_Error(RESOURCE_ERROR_STACK, arena, LOCAL_ErrorMessage); Yap_Error(RESOURCE_ERROR_STACK, arena, LOCAL_ErrorMessage);
return 0L; return 0L;
} }
to = ARG3; to = ARG3;
qd = RepAppl(Deref(ARG1)) + 1; qd = RepAppl(Deref(ARG1)) + 1;
arena = qd[HEAP_ARENA]; arena = qd[HEAP_ARENA];
oldH = HR;
oldHB = HB;
HR = HB = ArenaPt(arena); HR = HB = ArenaPt(arena);
old_sz = ArenaSz(arena); old_sz = ArenaSz(arena);
} }
@ -2042,7 +2033,7 @@ restart:
pt[2 * hsize + 1] = to; pt[2 * hsize + 1] = to;
PushHeap(pt, hsize); PushHeap(pt, hsize);
qd[HEAP_SIZE] = Global_MkIntegerTerm(hsize + 1); qd[HEAP_SIZE] = Global_MkIntegerTerm(hsize + 1);
CloseArena(oldH, oldHB, ASP, qd + HEAP_ARENA, old_sz PASS_REGS); CloseArena(&cspace, qd + HEAP_ARENA, old_sz PASS_REGS);
return TRUE; return TRUE;
} }
@ -2100,6 +2091,7 @@ static Int p_nb_heap_size(USES_REGS1) {
} }
static Int p_nb_beam(USES_REGS1) { static Int p_nb_beam(USES_REGS1) {
cell_space_t cspace;
Term beam_arena, beam, *ar, *nar; Term beam_arena, beam, *ar, *nar;
UInt hsize; UInt hsize;
Term tsize = Deref(ARG1); Term tsize = Deref(ARG1);
@ -2130,7 +2122,7 @@ static Int p_nb_beam(USES_REGS1) {
ar[HEAP_MAX] = tsize; ar[HEAP_MAX] = tsize;
if (arena_sz < 1024) if (arena_sz < 1024)
arena_sz = 1024; arena_sz = 1024;
beam_arena = NewArena(arena_sz, worker_id, 1, NULL); beam_arena = NewArena(arena_sz, worker_id, 1, NULL, &cspace);
if (beam_arena == 0L) { if (beam_arena == 0L) {
return FALSE; return FALSE;
} }
@ -2339,10 +2331,11 @@ static Term DelBeamMin(CELL *pt, CELL *pt2, UInt sz) {
} }
static Int p_nb_beam_add_to_beam(USES_REGS1) { static Int p_nb_beam_add_to_beam(USES_REGS1) {
CELL *qd = GetHeap(ARG1, "add_to_beam"), *oldH, *oldHB, *pt; CELL *qd = GetHeap(ARG1, "add_to_beam"), *pt;
UInt hsize, hmsize, old_sz; UInt hsize, hmsize, old_sz;
Term arena, to, key; Term arena, to, qsize, key;
UInt mingrow; UInt mingrow;
cell_space_t cspace;
if (!qd) if (!qd)
return FALSE; return FALSE;
@ -2373,37 +2366,32 @@ static Int p_nb_beam_add_to_beam(USES_REGS1) {
qd = GetHeap(ARG1, "add_to_beam"); qd = GetHeap(ARG1, "add_to_beam");
arena = qd[HEAP_ARENA]; arena = qd[HEAP_ARENA];
/* garbage collection ? */ /* garbage collection ? */
oldH = HR; enter_cell_space(&cspace);
oldHB = HB;
HR = HB = ArenaPt(arena); HR = HB = ArenaPt(arena);
old_sz = ArenaSz(arena); old_sz = ArenaSz(arena);
qsize = IntegerOfTerm(qd[QUEUE_SIZE]);
while (old_sz < MIN_ARENA_SIZE) { while (old_sz < MIN_ARENA_SIZE) {
UInt gsiz = hsize * 2; UInt gsiz = HR - RepPair(qd[QUEUE_HEAD]);
HR = oldH;
HB = oldHB;
if (gsiz > 1024 * 1024) { if (gsiz > 1024 * 1024) {
gsiz = 1024 * 1024; gsiz = 1024 * 1024;
} else if (gsiz < 1024) { } else if (gsiz < 1024) {
gsiz = 1024; gsiz = 1024;
} }
ARG3 = to; ARG3 = to;
if (!GrowArena(arena, ArenaLimit(arena), old_sz, gsiz, 3 PASS_REGS)) { /* fprintf(stderr,"growing %ld cells\n",(unsigned long int)gsiz);*/
if (!GrowArena(arena, ArenaLimit(arena), old_sz, gsiz, 3, &cspace PASS_REGS)) {
Yap_Error(RESOURCE_ERROR_STACK, arena, LOCAL_ErrorMessage); Yap_Error(RESOURCE_ERROR_STACK, arena, LOCAL_ErrorMessage);
return 0L; return 0L;
} }
to = ARG3; to = ARG3;
qd = RepAppl(Deref(ARG1)) + 1; qd = RepAppl(Deref(ARG1)) + 1;
arena = qd[HEAP_ARENA]; arena = qd[HEAP_ARENA];
oldH = HR;
oldHB = HB;
HR = HB = ArenaPt(arena);
old_sz = ArenaSz(arena); old_sz = ArenaSz(arena);
} }
pt = qd + HEAP_START; pt = qd + HEAP_START;
PushBeam(pt, pt + 2 * hmsize, hsize, key, to); PushBeam(pt, pt + 2 * hmsize, hsize, key, to);
qd[HEAP_SIZE] = Global_MkIntegerTerm(hsize + 1); qd[HEAP_SIZE] = Global_MkIntegerTerm(hsize + 1);
CloseArena(oldH, oldHB, ASP, qd + HEAP_ARENA, old_sz PASS_REGS); CloseArena(&cspace, qd + HEAP_ARENA, old_sz PASS_REGS);
return TRUE; return TRUE;
} }
@ -2411,8 +2399,8 @@ static Int p_nb_beam_del(USES_REGS1) {
CELL *qd = GetHeap(ARG1, "debeam"); CELL *qd = GetHeap(ARG1, "debeam");
UInt old_sz, qsz; UInt old_sz, qsz;
Term arena; Term arena;
CELL *oldH, *oldHB;
Term tk, tv; Term tk, tv;
cell_space_t cspace;
if (!qd) if (!qd)
return FALSE; return FALSE;
@ -2424,10 +2412,9 @@ static Int p_nb_beam_del(USES_REGS1) {
return FALSE; return FALSE;
old_sz = ArenaSz(arena); old_sz = ArenaSz(arena);
/* garbage collection ? */ /* garbage collection ? */
oldH = HR; enter_cell_space(&cspace);
oldHB = HB;
qd[HEAP_SIZE] = Global_MkIntegerTerm(qsz - 1); qd[HEAP_SIZE] = Global_MkIntegerTerm(qsz - 1);
CloseArena(oldH, oldHB, ASP, &arena, old_sz PASS_REGS); CloseArena(&cspace, &arena, old_sz PASS_REGS);
tk = qd[HEAP_START]; tk = qd[HEAP_START];
tv = DelBeamMin(qd + HEAP_START, tv = DelBeamMin(qd + HEAP_START,
qd + (HEAP_START + 2 * IntegerOfTerm(qd[HEAP_MAX])), qsz); qd + (HEAP_START + 2 * IntegerOfTerm(qd[HEAP_MAX])), qsz);

109
C/grow.c
View File

@ -324,15 +324,15 @@ MoveGlobalWithHole( USES_REGS1 )
} }
static void static void
MoveHalfGlobal(CELL *OldPt USES_REGS) MoveHalfGlobal(CELL *OldPt, size_t request USES_REGS)
{ {
/* /*
* cpcellsd(To,From,NOfCells) - copy the cells downwards - in * cpcellsd(To,From,NOfCells) - copy the cells downwards - in
* absmi.asm * absmi.asm
*/ */
UInt diff = LOCAL_OldH-OldPt; UInt diff = LOCAL_OldH-OldPt;
CELL *NewPt = (CELL *)((char*)OldPt+LOCAL_GDiff);
CELL *IntPt = (CELL *)((char*)OldPt+LOCAL_GDiff0); CELL *IntPt = (CELL *)((char*)OldPt+LOCAL_GDiff0);
CELL *NewPt = IntPt+request/sizeof(CELL);
cpcellsd(NewPt, IntPt, diff); cpcellsd(NewPt, IntPt, diff);
} }
@ -393,7 +393,7 @@ AdjustTrail(bool adjusting_heap, bool thread_copying USES_REGS)
register CELL reg = TrailTerm(ptt-1); register CELL reg = TrailTerm(ptt-1);
#ifdef FROZEN_STACKS #ifdef FROZEN_STACKS
register CELL reg2 = TrailVal(ptt-1); register CELL reg2 = TrailVal(ptt-1);
#endif #endif
ptt--; ptt--;
if (IsVarTerm(reg)) { if (IsVarTerm(reg)) {
@ -436,6 +436,8 @@ fixPointerCells(CELL *pt, CELL *pt_bot, bool thread_copying USES_REGS)
{ {
while (pt > pt_bot) { while (pt > pt_bot) {
CELL reg = *--pt; CELL reg = *--pt;
// if (pt-pt_bot> 4300 && pt-pt_bot < 4500)
// printf("%d %d %lx\n", pt-pt_bot, pt-LOCAL_GSplit, reg);
if (IsVarTerm(reg)) { if (IsVarTerm(reg)) {
if (IsOldLocal(reg)) if (IsOldLocal(reg))
*pt = LocalAdjust(reg); *pt = LocalAdjust(reg);
@ -450,6 +452,8 @@ fixPointerCells(CELL *pt, CELL *pt_bot, bool thread_copying USES_REGS)
} else if (IsPairTerm(reg)) { } else if (IsPairTerm(reg)) {
*pt = AdjustPair(reg PASS_REGS); *pt = AdjustPair(reg PASS_REGS);
} }
// if (pt-pt_bot> 4300 && pt-pt_bot < 4500)
// printf("%lx\n", *pt);
} }
} }
@ -889,12 +893,11 @@ static_growglobal(size_t request, CELL **ptr, CELL *hsplit USES_REGS)
char *omax = (char *)H0; char *omax = (char *)H0;
ADDR old_GlobalBase = LOCAL_GlobalBase; ADDR old_GlobalBase = LOCAL_GlobalBase;
UInt minimal_request = 0L; UInt minimal_request = 0L;
Int size = request; Int size = request/sizeof(CELL);
char vb_msg1 = '\0', *vb_msg2; char vb_msg1 = '\0', *vb_msg2;
bool do_grow = true; bool do_grow = true;
bool insert_in_delays = false;
/* /*
request is the amount of memory we requested, in bytes; request is the amount of memory we requesd, in bytes;
base_move is the shift in global stacks we had to do base_move is the shift in global stacks we had to do
size is how much space we allocate: it's negative if we just expand size is how much space we allocate: it's negative if we just expand
the delay stack. the delay stack.
@ -902,55 +905,42 @@ static_growglobal(size_t request, CELL **ptr, CELL *hsplit USES_REGS)
*/ */
if (hsplit) { if (hsplit) {
/* just a little bit of sanity checking */ if (hsplit < H0 ||
if (hsplit < H0 && hsplit > (CELL *)LOCAL_GlobalBase) {
insert_in_delays = TRUE;
/* expanding attributed variables */
if (omax - size > LOCAL_GlobalBase+4096*sizeof(CELL)) {
/* we can just ask for more room */
size = 0;
do_grow = FALSE;
}
} else if (hsplit < (CELL*)omax ||
hsplit > HR) hsplit > HR)
return FALSE; return false;
else if (hsplit == (CELL *)omax) if (hsplit == HR && Unsigned(HR)+request < Unsigned(ASP)-StackGap( PASS_REGS1 )) {
hsplit = NULL; return request;
if (size < 0 ||
(Unsigned(HR)+size < Unsigned(ASP)-StackGap( PASS_REGS1 ) &&
hsplit > H0)) {
/* don't need to expand stacks */
insert_in_delays = FALSE;
do_grow = FALSE;
}
} else {
if (Unsigned(HR)+size < Unsigned(ASP)-CreepFlag) {
/* we can just ask for more room */
do_grow = FALSE;
} }
} }
if (size < 0 ||
(Unsigned(HR)+request < Unsigned(ASP-StackGap( PASS_REGS1 )))) {
do_grow = false;
}
if (do_grow) { if (do_grow) {
if (size < YAP_ALLOC_SIZE) if (request < YAP_ALLOC_SIZE)
size = YAP_ALLOC_SIZE; request = YAP_ALLOC_SIZE;
size = AdjustPageSize(size); request = AdjustPageSize(request);
} }
printf("grow=%d\n", do_grow);
/* adjust to a multiple of 256) */ /* adjust to a multiple of 256) */
LOCAL_ErrorMessage = NULL; LOCAL_ErrorMessage = NULL;
LOCAL_PrologMode |= GrowStackMode; LOCAL_PrologMode |= GrowStackMode;
start_growth_time = Yap_cputime(); start_growth_time = Yap_cputime();
if (do_grow) { if (do_grow) {
if (!GLOBAL_AllowGlobalExpansion) { if (!GLOBAL_AllowGlobalExpansion) {
LOCAL_ErrorMessage = "Global Stack crashed against Local Stack"; LOCAL_ErrorMessage = "Global Stack crashed against Local Stack";
LeaveGrowMode(GrowStackMode); LeaveGrowMode(GrowStackMode);
return 0; return 0;
} }
if (!GLOBAL_AllowGlobalExpansion || !Yap_ExtendWorkSpace(size)) { if (!GLOBAL_AllowGlobalExpansion || !Yap_ExtendWorkSpace(request)) {
/* always fails when using malloc */ /* always fails when using malloc */
LOCAL_ErrorMessage = NULL; LOCAL_ErrorMessage = NULL;
size += AdjustPageSize(((CELL)LOCAL_TrailTop-(CELL)LOCAL_GlobalBase)+MinHeapGap); request += AdjustPageSize(((CELL)LOCAL_TrailTop-(CELL)LOCAL_GlobalBase)+MinHeapGap);
minimal_request = size; minimal_request = request;
size = Yap_ExtendWorkSpaceThroughHole(size); request = Yap_ExtendWorkSpaceThroughHole(request);
if (size < 0) { if (request < 0) {
LOCAL_ErrorMessage = "Global Stack crashed against Local Stack"; LOCAL_ErrorMessage = "Global Stack crashed against Local Stack";
LeaveGrowMode(GrowStackMode); LeaveGrowMode(GrowStackMode);
return 0; return 0;
@ -958,15 +948,11 @@ static_growglobal(size_t request, CELL **ptr, CELL *hsplit USES_REGS)
} }
} }
gc_verbose = Yap_is_gc_verbose(); gc_verbose = Yap_is_gc_verbose();
LOCAL_delay_overflows++;
if (gc_verbose) { if (gc_verbose) {
if (hsplit) { if (hsplit) {
if (hsplit > H0) { if (hsplit > H0) {
vb_msg1 = 'H'; vb_msg1 = 'H';
vb_msg2 = "Global Variable Space"; vb_msg2 = "Global Variable Space";
} else {
vb_msg1 = 'D';
vb_msg2 = "Global Variable Delay Space";
} }
} else { } else {
vb_msg1 = 'D'; vb_msg1 = 'D';
@ -976,8 +962,9 @@ static_growglobal(size_t request, CELL **ptr, CELL *hsplit USES_REGS)
fprintf(stderr, "%% Worker Id %d:\n", worker_id); fprintf(stderr, "%% Worker Id %d:\n", worker_id);
#endif #endif
fprintf(stderr, "%% %cO %s Overflow %d\n", vb_msg1, vb_msg2, LOCAL_delay_overflows); fprintf(stderr, "%% %cO %s Overflow %d\n", vb_msg1, vb_msg2, LOCAL_delay_overflows);
fprintf(stderr, "%% %cO growing the stacks " UInt_FORMAT " bytes\n", vb_msg1, size); fprintf(stderr, "%% %cO growing the stacks " UInt_FORMAT " bytes\n", vb_msg1, request);
} }
printf("grow=%d %p\n", do_grow, ASP);
ASP -= 256; ASP -= 256;
YAPEnterCriticalSection(); YAPEnterCriticalSection();
/* we always shift the local and the stack by the same amount */ /* we always shift the local and the stack by the same amount */
@ -985,13 +972,13 @@ static_growglobal(size_t request, CELL **ptr, CELL *hsplit USES_REGS)
/* we got over a hole */ /* we got over a hole */
if (minimal_request) { if (minimal_request) {
/* we went over a hole */ /* we went over a hole */
LOCAL_BaseDiff = size+((CELL)LOCAL_TrailTop-(CELL)LOCAL_GlobalBase)-minimal_request; LOCAL_BaseDiff = request+((CELL)LOCAL_TrailTop-(CELL)LOCAL_GlobalBase)-minimal_request;
LOCAL_LDiff = LOCAL_TrDiff = size; LOCAL_LDiff = LOCAL_TrDiff = request;
} else { } else {
/* we may still have an overflow */ /* we may still have an overflow */
LOCAL_BaseDiff = LOCAL_GlobalBase - old_GlobalBase; LOCAL_BaseDiff = LOCAL_GlobalBase - old_GlobalBase;
/* if we grow, we need to move the stacks */ /* if we grow, we need to move the stacks */
LOCAL_LDiff = LOCAL_TrDiff = LOCAL_BaseDiff+size; LOCAL_LDiff = LOCAL_TrDiff = LOCAL_BaseDiff+request;
} }
} else { } else {
/* stay still */ /* stay still */
@ -1002,25 +989,21 @@ static_growglobal(size_t request, CELL **ptr, CELL *hsplit USES_REGS)
hole in global */ hole in global */
if (!hsplit) { if (!hsplit) {
if (!do_grow) { if (!do_grow) {
LOCAL_DelayDiff = LOCAL_GDiff = LOCAL_GDiff0 = size; LOCAL_GDiff = LOCAL_GDiff0 = request;
request = 0L; request = 0L;
} else { } else {
/* expand delay stack */
LOCAL_DelayDiff = LOCAL_GDiff = LOCAL_GDiff0 = LOCAL_LDiff;
}
} else if (insert_in_delays) {
/* we want to expand a hole for the delay stack */ /* we want to expand a hole for the delay stack */
LOCAL_DelayDiff = size-request; LOCAL_GDiff = LOCAL_GDiff0 = LOCAL_LDiff;
LOCAL_GDiff = LOCAL_GDiff0 = size; }
} else { } else {
/* we want to expand a hole for the delay stack */ /* we want to expand a hole for the delay stack */
LOCAL_GDiff0 = LOCAL_DelayDiff = LOCAL_BaseDiff; LOCAL_GDiff0 = LOCAL_BaseDiff;
LOCAL_GDiff = LOCAL_BaseDiff+request; LOCAL_GDiff = LOCAL_BaseDiff+request;
} }
LOCAL_GSplit = hsplit; LOCAL_GSplit = hsplit;
LOCAL_XDiff = LOCAL_HDiff = 0; LOCAL_XDiff = LOCAL_HDiff = 0;
LOCAL_GlobalBase = old_GlobalBase; LOCAL_GlobalBase = old_GlobalBase;
SetHeapRegs(FALSE PASS_REGS); SetHeapRegs(FALSE PASS_REGS);
if (do_grow) { if (do_grow) {
MoveLocalAndTrail( PASS_REGS1 ); MoveLocalAndTrail( PASS_REGS1 );
if (hsplit) { if (hsplit) {
@ -1042,17 +1025,13 @@ static_growglobal(size_t request, CELL **ptr, CELL *hsplit USES_REGS)
*ptr = PtoLocAdjust(*ptr); *ptr = PtoLocAdjust(*ptr);
} }
if (hsplit) { if (hsplit) {
if (insert_in_delays) { MoveHalfGlobal(hsplit, request PASS_REGS);
/* we have things not quite where we want to have them */ printf("done\n");
cpcellsd((CELL *)(omax+LOCAL_DelayDiff), (CELL *)(omax+LOCAL_GDiff0), (ADDR)hsplit-omax);
} else {
MoveHalfGlobal(hsplit PASS_REGS);
}
} }
YAPLeaveCriticalSection(); YAPLeaveCriticalSection();
ASP += 256; ASP += 256;
if (minimal_request) { if (minimal_request) {
Yap_AllocHole(minimal_request, size); Yap_AllocHole(minimal_request, request);
} }
growth_time = Yap_cputime()-start_growth_time; growth_time = Yap_cputime()-start_growth_time;
LOCAL_total_delay_overflow_time += growth_time; LOCAL_total_delay_overflow_time += growth_time;
@ -1063,8 +1042,9 @@ static_growglobal(size_t request, CELL **ptr, CELL *hsplit USES_REGS)
LeaveGrowMode(GrowStackMode); LeaveGrowMode(GrowStackMode);
if (hsplit) { if (hsplit) {
return request; return request;
} else } else {
return LOCAL_GDiff-LOCAL_BaseDiff; return LOCAL_GDiff-LOCAL_BaseDiff;
}
} }
static void static void
@ -1503,7 +1483,7 @@ Yap_growheap(bool fix_code, size_t in_size, void *cip)
int int
Yap_growheap_in_parser(tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep) Yap_growheap_in_parser(tr_fr_ptr *old_trp, TokEntry **tksp, VarEntry **vep)
{ {
CACHE_REGS CACHE_REGS
int res; int res;
res=do_growheap(FALSE, 0L, NULL, old_trp, tksp, vep PASS_REGS); res=do_growheap(FALSE, 0L, NULL, old_trp, tksp, vep PASS_REGS);
@ -1576,6 +1556,7 @@ Yap_growstack(size_t size)
int res; int res;
LOCAL_PrologMode |= GrowStackMode; LOCAL_PrologMode |= GrowStackMode;
printf("extra %dBs\n",size);
res=growstack(size PASS_REGS); res=growstack(size PASS_REGS);
LeaveGrowMode(GrowStackMode); LeaveGrowMode(GrowStackMode);
return res; return res;

View File

@ -1,4 +1,4 @@
/************************************************************************** /*************************************************************************
* * * *
* YAP Prolog * * YAP Prolog *
* * * *
@ -2090,12 +2090,12 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, bool very_verbose
restart_cp: restart_cp:
switch (opnum) { switch (opnum) {
case _Nstop: case _Nstop:
if (gc_B->cp_b != NULL) { if (gc_B->cp_env == LCL0) {
nargs = 0; return;
break; } else {
} else { // This must be a border choicepoint, just move up
/* this is the last choice point, the work is done ;-) */ gc_B = (choiceptr)(gc_B->cp_env[E_B]);
return; continue;
} }
case _retry_c: case _retry_c:
case _retry_userc: case _retry_userc:
@ -3025,11 +3025,14 @@ sweep_choicepoints(choiceptr gc_B USES_REGS)
sweep_environments(gc_B->cp_env, sweep_environments(gc_B->cp_env,
EnvSizeInCells, EnvSizeInCells,
NULL PASS_REGS); NULL PASS_REGS);
if (gc_B->cp_b != NULL) { if (gc_B->cp_env == LCL0) {
break; return;
} else } else {
return; // This must be a border choicepoint, just move up
case _trust_fail: gc_B = (choiceptr)(gc_B->cp_env[E_B]);
continue;
}
case _trust_fail:
break; break;
case _or_else: case _or_else:
case _or_last: case _or_last:
@ -4191,7 +4194,7 @@ call_gc(UInt gc_lim, Int predarity, CELL *current_env, yamop *nextop USES_REGS)
int gc_on = FALSE, gc_t = FALSE; int gc_on = FALSE, gc_t = FALSE;
if (Yap_GetValue(AtomGc) != TermNil) if (Yap_GetValue(AtomGc) != TermNil)
gc_on = TRUE; gc_on = false;
if (IsIntegerTerm(Tgc_margin = Yap_GetValue(AtomGcMargin)) && if (IsIntegerTerm(Tgc_margin = Yap_GetValue(AtomGcMargin)) &&
gc_margin > 0) { gc_margin > 0) {
gc_margin = (UInt)IntegerOfTerm(Tgc_margin); gc_margin = (UInt)IntegerOfTerm(Tgc_margin);
@ -4343,3 +4346,4 @@ Yap_inc_mark_variable()
CACHE_REGS CACHE_REGS
LOCAL_total_marked++; LOCAL_total_marked++;
} }

View File

@ -2039,7 +2039,7 @@ static UInt suspend_indexing(ClauseDef *min, ClauseDef *max, PredEntry *ap,
/* give it some slack */ /* give it some slack */
tels = cls + 4; tels = cls + 4;
} else { } else {
tels = cls; tels = cls+1;
} }
sz = (UInt)NEXTOP((yamop *)NULL, sssllp) + tels * sizeof(yamop *); sz = (UInt)NEXTOP((yamop *)NULL, sssllp) + tels * sizeof(yamop *);
if ((ncode = (yamop *)Yap_AllocCodeSpace(sz)) == NULL) { if ((ncode = (yamop *)Yap_AllocCodeSpace(sz)) == NULL) {

View File

@ -470,6 +470,7 @@
LogUpdClause *lcl = PREG->y_u.OtILl.d; LogUpdClause *lcl = PREG->y_u.OtILl.d;
UInt timestamp = IntegerOfTerm(((CELL *)(B_YREG+1))[ap->ArityOfPE]); UInt timestamp = IntegerOfTerm(((CELL *)(B_YREG+1))[ap->ArityOfPE]);
/* fprintf(stderr,"- %p/%p %d %d %p\n",PREG,ap,timestamp,ap->TimeStampOfPred,PREG->y_u.OtILl.d->ClCode);*/
#if defined(YAPOR) || defined(THREADS) #if defined(YAPOR) || defined(THREADS)
if (PP != ap) { if (PP != ap) {
if (PP) UNLOCKPE(16,PP); if (PP) UNLOCKPE(16,PP);

View File

@ -1949,12 +1949,12 @@
Op(p_arg_vv, xxx); Op(p_arg_vv, xxx);
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; Term ts[3];
HRs[0] = XREG(PREG->y_u.xxx.x1); ts[0] = XREG(PREG->y_u.xxx.x1);
HRs[1] = XREG(PREG->y_u.xxx.x2); ts[1] = XREG(PREG->y_u.xxx.x2);
HRs[2] = TermNil; RESET_VARIABLE(ts + 2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorArg, 0)), HRs); RepPredProp(Yap_GetPredPropByFunc(FunctorArg, 0)), ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);
@ -2045,14 +2045,16 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
Op(p_arg_cv, xxn); Op(p_arg_cv, xxn);
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; CELL *Ho = HR;
Term ts[3];
Term t = MkIntegerTerm(PREG->y_u.xxn.c); Term t = MkIntegerTerm(PREG->y_u.xxn.c);
HRs[0] = t; ts[0] = t;
HRs[1] = XREG(PREG->y_u.xxn.xi); ts[1] = XREG(PREG->y_u.xxn.xi);
HRs[2] = TermFoundVar; RESET_VARIABLE(ts + 2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorArg, 0)), HRs); RepPredProp(Yap_GetPredPropByFunc(FunctorArg, 0)), ts);
} HR = Ho;
}
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);
d0 = PREG->y_u.xxn.c; d0 = PREG->y_u.xxn.c;
@ -2118,13 +2120,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
Op(p_arg_y_vv, yxx); Op(p_arg_y_vv, yxx);
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; Term ts[3];
ts[0] = XREG(PREG->y_u.yxx.x1);
HRs[0] = XREG(PREG->y_u.yxx.x1); ts[1] = XREG(PREG->y_u.yxx.x2);
HRs[1] = XREG(PREG->y_u.yxx.x2); ts[2] = YREG[PREG->y_u.yxx.y];
HRs[2] = TermFoundVar; RESET_VARIABLE(ts + 2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorArg, 0)), HRs); RepPredProp(Yap_GetPredPropByFunc(FunctorArg, 0)), ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);
@ -2216,13 +2218,16 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
Op(p_arg_y_cv, yxn); Op(p_arg_y_cv, yxn);
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; CELL *Ho = HR;
Term ts[3];
Term t = MkIntegerTerm(PREG->y_u.yxn.c); Term t = MkIntegerTerm(PREG->y_u.yxn.c);
HRs[0] = t; ts[0] = t;
HRs[1] = XREG(PREG->y_u.yxn.xi); ts[1] = XREG(PREG->y_u.yxn.xi);
HRs[2] = TermNil; ts[2] = YREG[PREG->y_u.yxn.y];
RESET_VARIABLE(ts + 2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorArg, 0)), HRs); RepPredProp(Yap_GetPredPropByFunc(FunctorArg, 0)), ts);
HR = Ho;
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);
@ -2294,13 +2299,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
restart_func2s: restart_func2s:
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; Term ts[3];
HRs[0] = TermNil; RESET_VARIABLE(ts);
HRs[1] = XREG(PREG->y_u.xxx.x1); ts[1] = XREG(PREG->y_u.xxx.x1);
HRs[2] = XREG(PREG->y_u.xxx.x2); ts[2] = XREG(PREG->y_u.xxx.x2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
/* We have to build the structure */ /* We have to build the structure */
@ -2412,13 +2417,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
restart_func2s_cv: restart_func2s_cv:
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; Term ts[3];
HRs[0] = TermNil; RESET_VARIABLE(ts);
HRs[1] = PREG->y_u.xxc.c; ts[1] = PREG->y_u.xxc.c;
HRs[2] = XREG(PREG->y_u.xxc.xi); ts[2] = XREG(PREG->y_u.xxc.xi);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);
@ -2518,14 +2523,17 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
Term ti; Term ti;
CELL HRs[3]; Term ts[3];
HRs[0] = TermNil; CELL *hi = HR;
ti = MkIntegerTerm(PREG->y_u.xxn.c); ti = MkIntegerTerm(PREG->y_u.xxn.c);
HRs[1] = XREG(PREG->y_u.xxn.xi); RESET_VARIABLE(ts);
HRs[2] = ti; ts[1] = XREG(PREG->y_u.xxn.xi);
ts[2] = ti;
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
HR = hi;
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
/* We have to build the structure */ /* We have to build the structure */
@ -2610,13 +2618,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
restart_func2s_y: restart_func2s_y:
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; Term ts[3];
HRs[0] = TermNil; RESET_VARIABLE(ts);
HRs[1] = XREG(PREG->y_u.yxx.x1); ts[1] = XREG(PREG->y_u.yxx.x1);
HRs[2] = XREG(PREG->y_u.yxx.x2); ts[2] = XREG(PREG->y_u.yxx.x2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
/* We have to build the structure */ /* We have to build the structure */
@ -2735,13 +2743,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
restart_func2s_y_cv: restart_func2s_y_cv:
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; Term ts[3];
HRs[0] = TermNil; RESET_VARIABLE(ts);
HRs[1] = PREG->y_u.yxc.c; ts[1] = PREG->y_u.yxc.c;
HRs[2] = XREG(PREG->y_u.yxc.xi); ts[2] = XREG(PREG->y_u.yxc.xi);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
/* We have to build the structure */ /* We have to build the structure */
@ -2847,15 +2855,17 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
Term ti; Term ti;
CELL HRs[3]; CELL *hi = HR;
Term ts[3];
ti = MkIntegerTerm((Int)(PREG->y_u.yxn.c)); ti = MkIntegerTerm((Int)(PREG->y_u.yxn.c));
HRs[0] = TermFoundVar; RESET_VARIABLE(ts);
HRs[1] = XREG(PREG->y_u.yxn.xi); ts[1] = XREG(PREG->y_u.yxn.xi);
HRs[2] = ti; ts[2] = ti;
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
HR = hi;
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
/* We have to build the structure */ /* We have to build the structure */
@ -2952,12 +2962,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
Op(p_func2f_xx, xxx); Op(p_func2f_xx, xxx);
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
Term HRs[3]; Term ts[3];
HRs[0] = XREG(PREG->y_u.xxx.x); ts[0] = XREG(PREG->y_u.xxx.x);
HRs[1] = HRs[2] = TermFoundVar; RESET_VARIABLE(ts + 1);
RESET_VARIABLE(ts + 2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);
@ -3000,12 +3011,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
Op(p_func2f_xy, xxy); Op(p_func2f_xy, xxy);
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
Term HRs[3]; Term ts[3];
HRs[0] = XREG(PREG->y_u.xxy.x); ts[0] = XREG(PREG->y_u.xxy.x);
HRs[1] = HRs[2] = TermFoundVar; RESET_VARIABLE(ts + 1);
RESET_VARIABLE(ts + 2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);
@ -3051,12 +3063,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
Op(p_func2f_yx, yxx); Op(p_func2f_yx, yxx);
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
Term HRs[3]; Term ts[3];
HRs[0] = XREG(PREG->y_u.yxx.x2); ts[0] = XREG(PREG->y_u.yxx.x2);
HRs[1] = HRs[2] = TermFoundVar; RESET_VARIABLE(ts + 1);
RESET_VARIABLE(ts + 2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);
@ -3102,12 +3115,13 @@ Yap_AsmError( DOMAIN_ERROR_NOT_LESS_THAN_ZERO );
Op(p_func2f_yy, yyx); Op(p_func2f_yy, yyx);
#ifdef LOW_LEVEL_TRACER #ifdef LOW_LEVEL_TRACER
if (Yap_do_low_level_trace) { if (Yap_do_low_level_trace) {
CELL HRs[3]; Term ts[3];
HRs[0] = XREG(PREG->y_u.yyx.x); ts[0] = XREG(PREG->y_u.yyx.x);
HRs[1] = HRs[2] = TermFoundVar; RESET_VARIABLE(ts + 1);
RESET_VARIABLE(ts + 2);
low_level_trace(enter_pred, low_level_trace(enter_pred,
RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)), RepPredProp(Yap_GetPredPropByFunc(FunctorFunctor, 0)),
HRs); ts);
} }
#endif /* LOW_LEVEL_TRACE */ #endif /* LOW_LEVEL_TRACE */
BEGD(d0); BEGD(d0);

View File

@ -435,7 +435,7 @@ writing, writing a BOM can be requested using the option
#define my_islower(C) (C >= 'a' && C <= 'z') #define my_islower(C) (C >= 'a' && C <= 'z')
static Term float_send(char *, int); static Term float_send(char *, int);
static Term get_num(int *, int *, struct stream_desc *, int); static Term get_num(int *, int *, struct stream_desc *, int, char **, size_t *);
static void Yap_setCurrentSourceLocation(struct stream_desc *s) { static void Yap_setCurrentSourceLocation(struct stream_desc *s) {
CACHE_REGS CACHE_REGS
@ -579,21 +579,6 @@ static TokEntry *TrailSpaceError__(TokEntry *t, TokEntry *l USES_REGS) {
return l; return l;
} }
#define AuxSpaceError(p, l, msg) AuxSpaceError__(p, l, msg PASS_REGS)
static TokEntry *AuxSpaceError__(TokEntry *p, TokEntry *l,
const char *msg USES_REGS) {
/* huge atom or variable, we are in trouble */
LOCAL_ErrorMessage = (char *)msg;
LOCAL_Error_TYPE = RESOURCE_ERROR_AUXILIARY_STACK;
Yap_ReleasePreAllocCodeSpace((COBEADDR)TokImage);
if (p) {
p->Tok = eot_tok;
p->TokInfo = TermOutOfAuxspaceError;
}
/* serious error now */
return l;
}
static void *InitScannerMemory(void) { static void *InitScannerMemory(void) {
CACHE_REGS CACHE_REGS
LOCAL_ErrorMessage = NULL; LOCAL_ErrorMessage = NULL;
@ -879,32 +864,22 @@ static int num_send_error_message(char s[]) {
#define number_overflow() \ #define number_overflow() \
{ \ { \
size_t nsz = Yap_Min(max_size * 2, max_size); \ imgsz = Yap_Min(imgsz * 2, imgsz); \
char *nbuf; \ char *nbuf; \
\ nbuf = Realloc(buf, imgsz); left = imgsz - max_size; \
if (buf == buf0) { \ max_size = imgsz; \
nbuf = Malloc(nsz); \
} else { \
nbuf = realloc(buf, nsz); \
} \
if (!nbuf) { \
return num_send_error_message("Number Too Long"); \
} else { \
left = nsz - max_size; \
max_size = nsz; \
buf = nbuf; \ buf = nbuf; \
} \
} }
/* reads a number, either integer or float */ /* reads a number, either integer or float */
static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign) { static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign, char **bufp, size_t *szp) {
int ch = *chp; int ch = *chp;
Int val = 0L, base = ch - '0'; Int val = 0L, base = ch - '0';
int might_be_float = TRUE, has_overflow = FALSE; int might_be_float = TRUE, has_overflow = FALSE;
const unsigned char *decimalpoint; const unsigned char *decimalpoint;
char buf0[256], *sp = buf0, *buf = buf0; char *buf0 = *bufp, *sp = buf0, *buf = buf0;
int max_size = 254, left = 254; size_t imgsz = *szp, max_size = imgsz, left = max_size-2;
*sp++ = ch; *sp++ = ch;
ch = getchr(st); ch = getchr(st);
@ -1167,7 +1142,11 @@ Term Yap_scan_num(StreamDesc *inp, bool error_on) {
LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; LOCAL_Error_TYPE = RESOURCE_ERROR_STACK;
return 0; return 0;
} }
out = get_num(&ch, &cherr, inp, sign); /* */ size_t sz = 1024;
char *buf = Malloc(sz);
int lvl = push_text_stack();
out = get_num(&ch, &cherr, inp, sign, &buf, &sz); /* */
pop_text_stack(lvl);
} else { } else {
out = 0; out = 0;
} }
@ -1340,9 +1319,13 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
TokEntry *t, *l, *p; TokEntry *t, *l, *p;
enum TokenKinds kind; enum TokenKinds kind;
int solo_flag = TRUE; int solo_flag = TRUE;
int lvl = push_text_stack();
int32_t ch, och = ' '; int32_t ch, och = ' ';
struct qq_struct_t *cur_qq = NULL; struct qq_struct_t *cur_qq = NULL;
int sign = 1; int sign = 1;
size_t imgsz = 1024;
char *TokImage = Malloc(imgsz PASS_REGS);
InitScannerMemory(); InitScannerMemory();
LOCAL_VarTable = NULL; LOCAL_VarTable = NULL;
@ -1362,11 +1345,11 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
int quote, isvar; int quote, isvar;
unsigned char *charp, *mp; unsigned char *charp, *mp;
size_t len; size_t len;
unsigned char *TokImage = NULL;
t = (TokEntry *)AllocScannerMemory(sizeof(TokEntry)); t = (TokEntry *)AllocScannerMemory(sizeof(TokEntry));
t->TokNext = NULL; t->TokNext = NULL;
if (t == NULL) { if (t == NULL) {
pop_text_stack(lvl);
return TrailSpaceError(p, l); return TrailSpaceError(p, l);
} }
if (!l) if (!l)
@ -1428,27 +1411,27 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
ch = getchr(st); ch = getchr(st);
scan_name: scan_name:
{ {
size_t sz = 1024;
TokImage = Malloc(sz PASS_REGS);
charp = (unsigned char *)TokImage; charp = (unsigned char *)TokImage;
isvar = (chtype(och) != LC); isvar = (chtype(och) != LC);
add_ch_to_buff(och); add_ch_to_buff(och);
for (; chtype(ch) <= NU; ch = getchr(st)) { for (; chtype(ch) <= NU; ch = getchr(st)) {
if (charp == TokImage + (sz - 1)) { if (charp == (unsigned char *)TokImage + (imgsz - 1)) {
unsigned char *p0 = TokImage; unsigned char *p0 = (unsigned char *)TokImage;
sz = Yap_Min(sz * 2, sz + MBYTE); imgsz = Yap_Min(imgsz * 2, imgsz + MBYTE);
TokImage = Realloc(p0, sz); TokImage = Realloc(p0, imgsz);
if (TokImage == NULL) { if (TokImage == NULL) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
charp = TokImage + (charp - p0); charp =(unsigned char *) TokImage + (charp - p0);
} }
add_ch_to_buff(ch); add_ch_to_buff(ch);
} }
while (ch == '\'' && isvar && while (ch == '\'' && isvar &&
trueGlobalPrologFlag(VARIABLE_NAMES_MAY_END_WITH_QUOTES_FLAG)) { trueGlobalPrologFlag(VARIABLE_NAMES_MAY_END_WITH_QUOTES_FLAG)) {
if (charp == (unsigned char *)AuxSp - 1024) { if (charp == (unsigned char *)AuxSp - 1024) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
add_ch_to_buff(ch); add_ch_to_buff(ch);
ch = getchr(st); ch = getchr(st);
@ -1457,10 +1440,10 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
if (!isvar) { if (!isvar) {
Atom ae; Atom ae;
/* don't do this in iso */ /* don't do this in iso */
ae = Yap_ULookupAtom(TokImage); ae = Yap_LookupAtom(TokImage);
Free(TokImage);
if (ae == NIL) { if (ae == NIL) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
t->TokInfo = MkAtomTerm(ae); t->TokInfo = MkAtomTerm(ae);
if (ch == '(') if (ch == '(')
@ -1468,7 +1451,6 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
t->Tok = Ord(kind = Name_tok); t->Tok = Ord(kind = Name_tok);
} else { } else {
VarEntry *ve = Yap_LookupVar((const char *)TokImage); VarEntry *ve = Yap_LookupVar((const char *)TokImage);
Free(TokImage);
t->TokInfo = Unsigned(ve); t->TokInfo = Unsigned(ve);
if (cur_qq) { if (cur_qq) {
ve->refs++; ve->refs++;
@ -1487,13 +1469,14 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
cha = ch; cha = ch;
cherr = 0; cherr = 0;
CHECK_SPACE(); CHECK_SPACE();
if ((t->TokInfo = get_num(&cha, &cherr, st, sign)) == 0L) { if ((t->TokInfo = get_num(&cha, &cherr, st, sign,&TokImage,&imgsz)) == 0L) {
if (t->TokInfo == 0) { if (t->TokInfo == 0) {
p->Tok = eot_tok; p->Tok = eot_tok;
t->TokInfo = TermError; t->TokInfo = TermError;
} }
/* serious error now */ /* serious error now */
return l; pop_text_stack(lvl);
return l;
} }
ch = cha; ch = cha;
if (cherr) { if (cherr) {
@ -1503,7 +1486,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
t->TokLine = GetCurInpLine(st); t->TokLine = GetCurInpLine(st);
e = (TokEntry *)AllocScannerMemory(sizeof(TokEntry)); e = (TokEntry *)AllocScannerMemory(sizeof(TokEntry));
if (e == NULL) { if (e == NULL) {
return TrailSpaceError(p, l); pop_text_stack(lvl);
return TrailSpaceError(p, l);
} else { } else {
e->TokNext = NULL; e->TokNext = NULL;
@ -1529,7 +1513,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
t->TokLine = GetCurInpLine(st); t->TokLine = GetCurInpLine(st);
e2 = (TokEntry *)AllocScannerMemory(sizeof(TokEntry)); e2 = (TokEntry *)AllocScannerMemory(sizeof(TokEntry));
if (e2 == NULL) { if (e2 == NULL) {
return TrailSpaceError(p, l); pop_text_stack(lvl);
return TrailSpaceError(p, l);
} else { } else {
e2->TokNext = NULL; e2->TokNext = NULL;
} }
@ -1563,7 +1548,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
t->TokPos = GetCurInpPos(st); t->TokPos = GetCurInpPos(st);
e2 = (TokEntry *)AllocScannerMemory(sizeof(TokEntry)); e2 = (TokEntry *)AllocScannerMemory(sizeof(TokEntry));
if (e2 == NULL) { if (e2 == NULL) {
return TrailSpaceError(p, l); pop_text_stack(lvl);
return TrailSpaceError(p, l);
} else { } else {
e2->TokNext = NULL; e2->TokNext = NULL;
} }
@ -1583,21 +1569,20 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
case QT: case QT:
case DC: case DC:
quoted_string: quoted_string:
TokImage = Malloc(1048); charp =(unsigned char *) TokImage;
charp = TokImage;
quote = ch; quote = ch;
len = 0; len = 0;
ch = getchrq(st); ch = getchrq(st);
size_t sz = 1024;
while (TRUE) { while (TRUE) {
if (charp > TokImage + (sz - 1)) { if (charp > (unsigned char *)TokImage + (imgsz - 1)) {
size_t sz = charp-TokImage; size_t sz = charp-(unsigned char *)TokImage;
TokImage = Realloc(TokImage, Yap_Min(sz * 2, sz + MBYTE)); TokImage = Realloc(TokImage, (imgsz = Yap_Min(imgsz * 2, imgsz + MBYTE)));
if (TokImage == NULL) { if (TokImage == NULL) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
charp = TokImage+sz; charp = (unsigned char *)TokImage+sz;
break; break;
} }
if (ch == 10 && trueGlobalPrologFlag(ISO_FLAG)) { if (ch == 10 && trueGlobalPrologFlag(ISO_FLAG)) {
@ -1634,22 +1619,24 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
t->TokInfo = Yap_CharsToTDQ((char *)TokImage, CurrentModule, t->TokInfo = Yap_CharsToTDQ((char *)TokImage, CurrentModule,
LOCAL_encoding PASS_REGS); LOCAL_encoding PASS_REGS);
if (!(t->TokInfo)) { if (!(t->TokInfo)) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
t->Tok = Ord(kind = String_tok); t->Tok = Ord(kind = String_tok);
} else if (quote == '`') { } else if (quote == '`') {
t->TokInfo = Yap_CharsToTBQ((char *)TokImage, CurrentModule, t->TokInfo = Yap_CharsToTBQ((char *)TokImage, CurrentModule,
LOCAL_encoding PASS_REGS); LOCAL_encoding PASS_REGS);
if (!(t->TokInfo)) { if (!(t->TokInfo)) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
t->Tok = Ord(kind = String_tok); t->Tok = Ord(kind = String_tok);
} else { } else {
t->TokInfo = MkAtomTerm(Yap_ULookupAtom(TokImage)); t->TokInfo = MkAtomTerm(Yap_LookupAtom(TokImage));
if (!(t->TokInfo)) { if (!(t->TokInfo)) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
Free(TokImage);
t->Tok = Ord(kind = Name_tok); t->Tok = Ord(kind = Name_tok);
if (ch == '(') if (ch == '(')
solo_flag = false; solo_flag = false;
@ -1668,7 +1655,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
t->TokInfo = TermNewLine; t->TokInfo = TermNewLine;
} }
t->TokInfo = TermEof; t->TokInfo = TermEof;
return l; pop_text_stack(lvl);
return l;
} else } else
ch = getchr(st); ch = getchr(st);
break; break;
@ -1682,9 +1670,11 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
// consume... // consume...
if (pch == '%') { if (pch == '%') {
t->TokInfo = TermNewLine; t->TokInfo = TermNewLine;
return l; pop_text_stack(lvl);
return l;
} }
return l; pop_text_stack(lvl);
return l;
} }
if (ch == '`') if (ch == '`')
goto quoted_string; goto quoted_string;
@ -1695,7 +1685,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
if (ch == '%') { if (ch == '%') {
t->TokInfo = TermNewLine; t->TokInfo = TermNewLine;
return l; pop_text_stack(lvl);
return l;
} }
if (chtype(ch) == EF) { if (chtype(ch) == EF) {
mark_eof(st); mark_eof(st);
@ -1703,7 +1694,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
} else { } else {
t->TokInfo = TermNewLine; t->TokInfo = TermNewLine;
} }
return l; pop_text_stack(lvl);
return l;
} }
} }
if (och == '/' && ch == '*') { if (och == '/' && ch == '*') {
@ -1752,7 +1744,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
if (ch == '%') { if (ch == '%') {
t->TokInfo = TermNewLine; t->TokInfo = TermNewLine;
return l; pop_text_stack(lvl);
return l;
} }
if (chtype(ch) == EF) { if (chtype(ch) == EF) {
mark_eof(st); mark_eof(st);
@ -1760,32 +1753,36 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
} else { } else {
t->TokInfo = TermNl; t->TokInfo = TermNl;
} }
return l; pop_text_stack(lvl);
return l;
} else { } else {
Atom ae; Atom ae;
sz = 1024; charp = (unsigned char *)TokImage;
TokImage = Malloc(sz);
charp = TokImage;
add_ch_to_buff(och); add_ch_to_buff(och);
for (; chtype(ch) == SY; ch = getchr(st)) { for (; chtype(ch) == SY; ch = getchr(st)) {
if (charp >= TokImage + (sz - 10)) { if (charp >= (unsigned char *)TokImage + (imgsz - 10)) {
sz = Yap_Min(sz * 2, sz + MBYTE); size_t sz = charp - (unsigned char *)TokImage;
TokImage = Realloc(TokImage, sz); imgsz = Yap_Min(imgsz * 2, imgsz + MBYTE);
if (!TokImage) TokImage = Realloc(TokImage, imgsz);
return CodeSpaceError(t, p, l); if (!TokImage) {
pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
}
charp = (unsigned char *)TokImage+sz;
} }
add_ch_to_buff(ch); add_ch_to_buff(ch);
} }
add_ch_to_buff('\0'); add_ch_to_buff('\0');
ae = Yap_ULookupAtom(TokImage); ae = Yap_LookupAtom(TokImage);
if (ae == NIL) { if (ae == NIL) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
t->TokInfo = MkAtomTerm(ae); t->TokInfo = MkAtomTerm(ae);
if (t->TokInfo == (CELL)NIL) { if (t->TokInfo == (CELL)NIL) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
Free(TokImage);
t->Tok = Ord(kind = Name_tok); t->Tok = Ord(kind = Name_tok);
if (ch == '(') if (ch == '(')
solo_flag = false; solo_flag = false;
@ -1809,8 +1806,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
och = ch; och = ch;
ch = getchr(st); ch = getchr(st);
{ {
unsigned char chs[10]; unsigned char *chs;
TokImage = charp = chs; charp = chs = (unsigned char *)TokImage;
add_ch_to_buff(och); add_ch_to_buff(och);
charp[0] = '\0'; charp[0] = '\0';
t->TokInfo = MkAtomTerm(Yap_ULookupAtom(chs)); t->TokInfo = MkAtomTerm(Yap_ULookupAtom(chs));
@ -1847,15 +1844,16 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
LOCAL_ErrorMessage = "not enough heap space to read in quasi quote"; LOCAL_ErrorMessage = "not enough heap space to read in quasi quote";
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
t->TokInfo = TermOutOfHeapError; t->TokInfo = TermOutOfHeapError;
return l; pop_text_stack(lvl);
return l;
} }
if (cur_qq) { if (cur_qq) {
LOCAL_ErrorMessage = "quasi quote in quasi quote"; LOCAL_ErrorMessage = "quasi quote in quasi quote";
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
t->TokInfo = TermOutOfHeapError; t->TokInfo = TermOutOfHeapError;
Free(qq); pop_text_stack(lvl);
return l; return l;
} else { } else {
cur_qq = qq; cur_qq = qq;
} }
@ -1892,7 +1890,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
cur_qq = NULL; cur_qq = NULL;
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
t->TokInfo = TermError; t->TokInfo = TermError;
return l; pop_text_stack(lvl);
return l;
} }
cur_qq = NULL; cur_qq = NULL;
t->TokInfo = (CELL)qq; t->TokInfo = (CELL)qq;
@ -1906,16 +1905,7 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
qq->mid.charno = st->charcount - 1; qq->mid.charno = st->charcount - 1;
t->Tok = Ord(kind = QuasiQuotes_tok); t->Tok = Ord(kind = QuasiQuotes_tok);
ch = getchr(st); ch = getchr(st);
sz = 1024; charp = (unsigned char *)TokImage;
TokImage = Malloc(sz);
if (!TokImage) {
LOCAL_ErrorMessage =
"not enough heap space to read in a quasi quoted atom";
t->Tok = Ord(kind = eot_tok);
t->TokInfo = TermError;
return l;
}
charp = TokImage;
quote = ch; quote = ch;
len = 0; len = 0;
ch = getchrq(st); ch = getchrq(st);
@ -1931,7 +1921,6 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
break; break;
} }
} else if (chtype(ch) == EF) { } else if (chtype(ch) == EF) {
Free(TokImage);
mark_eof(st); mark_eof(st);
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
t->TokInfo = TermOutOfHeapError; t->TokInfo = TermOutOfHeapError;
@ -1940,24 +1929,18 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
charp += put_utf8(charp, ch); charp += put_utf8(charp, ch);
ch = getchrq(st); ch = getchrq(st);
} }
if (charp > (unsigned char *)AuxSp - 1024) {
/* Not enough space to read in the string. */
return AuxSpaceError(
t, l, "not enough space to read in string or quoted atom");
}
} }
len = charp - (unsigned char *)TokImage; len = charp - (unsigned char *)TokImage;
mp = Malloc(len + 1); mp = malloc(len + 1);
if (mp == NULL) { if (mp == NULL) {
LOCAL_ErrorMessage = "not enough heap space to read in quasi quote"; LOCAL_ErrorMessage = "not enough heap space to read in quasi quote";
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
t->TokInfo = TermOutOfHeapError; t->TokInfo = TermOutOfHeapError;
return l; pop_text_stack(lvl);
return l;
} }
strncpy((char *)mp, (const char *)TokImage, len + 1); strncpy((char *)mp, (const char *)TokImage, len + 1);
qq->text = (unsigned char *)mp; qq->text = (unsigned char *)mp;
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
if (st->status & Seekable_Stream_f) { if (st->status & Seekable_Stream_f) {
qq->end.byteno = fseek(st->file, 0, 0); qq->end.byteno = fseek(st->file, 0, 0);
} else { } else {
@ -1967,7 +1950,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
qq->end.linepos = st->linepos - 1; qq->end.linepos = st->linepos - 1;
qq->end.charno = st->charcount - 1; qq->end.charno = st->charcount - 1;
if (!(t->TokInfo)) { if (!(t->TokInfo)) {
return CodeSpaceError(t, p, l); pop_text_stack(lvl);
return CodeSpaceError(t, p, l);
} }
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
solo_flag = FALSE; solo_flag = FALSE;
@ -1980,7 +1964,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
mark_eof(st); mark_eof(st);
t->Tok = Ord(kind = eot_tok); t->Tok = Ord(kind = eot_tok);
t->TokInfo = TermEof; t->TokInfo = TermEof;
return l; pop_text_stack(lvl);
return l;
default: { default: {
kind = Error_tok; kind = Error_tok;
@ -1995,7 +1980,8 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
/* insert an error token to inform the system of what happened */ /* insert an error token to inform the system of what happened */
TokEntry *e = (TokEntry *)AllocScannerMemory(sizeof(TokEntry)); TokEntry *e = (TokEntry *)AllocScannerMemory(sizeof(TokEntry));
if (e == NULL) { if (e == NULL) {
return TrailSpaceError(p, l); pop_text_stack(lvl);
return TrailSpaceError(p, l);
} }
p->TokNext = e; p->TokNext = e;
e->Tok = Error_tok; e->Tok = Error_tok;
@ -2007,6 +1993,7 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments,
p = e; p = e;
} }
} while (kind != eot_tok); } while (kind != eot_tok);
pop_text_stack(lvl);
return (l); return (l);
} }

View File

@ -1579,6 +1579,7 @@ void Yap_InitCPreds(void) {
Yap_InitGlobals(); Yap_InitGlobals();
Yap_InitInlines(); Yap_InitInlines();
Yap_InitIOPreds(); Yap_InitIOPreds();
Yap_InitDBLoadPreds();
Yap_InitExoPreds(); Yap_InitExoPreds();
Yap_InitLoadForeign(); Yap_InitLoadForeign();
Yap_InitModulesC(); Yap_InitModulesC();

141
C/terms.c
View File

@ -82,25 +82,20 @@ typedef struct non_single_struct_t {
#define WALK_COMPLEX_TERM__(LIST0, STRUCT0, PRIMI0) \ #define WALK_COMPLEX_TERM__(LIST0, STRUCT0, PRIMI0) \
\ \
int lvl = push_text_stack();\ reset:\
CELL *pt0, *pt0_end; \ lvl = push_text_stack();\
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);\ to_visit0 = Malloc(auxsz); \
struct non_single_struct_t *to_visit0=NULL, *to_visit,* to_visit_max;\ pt0 = pt0_; pt0_end = pt0_end_; \
CELL *InitialH = HR;\ to_visit = to_visit0, \
tr_fr_ptr TR0 = TR;\ to_visit_max = to_visit + auxsz/sizeof(struct non_single_struct_t);\
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { \ \
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { \
/* Trail overflow */\ /* Trail overflow */\
goto trail_overflow;\ goto trail_overflow;\
}\ }\
if (HR + 1024 > ASP) { \ if (HR + 1024 > ASP) { \
goto global_overflow;\ goto global_overflow;\
}\ }\
reset:\
to_visit0 = Realloc(to_visit0,auxsz); \
pt0 = pt0_; pt0_end = pt0_end_; \
to_visit = to_visit0, \
to_visit_max = to_visit + auxsz/sizeof(struct non_single_struct_t);\
\
while (to_visit >= to_visit0) { \ while (to_visit >= to_visit0) { \
CELL d0; \ CELL d0; \
CELL *ptd0; \ CELL *ptd0; \
@ -193,7 +188,8 @@ aux_overflow : { \
} \ } \
clean_tr(TR0 PASS_REGS); \ clean_tr(TR0 PASS_REGS); \
auxsz += auxsz;\ auxsz += auxsz;\
goto reset; } pop_text_stack(lvl); \
goto reset; }
#define def_trail_overflow() \ #define def_trail_overflow() \
trail_overflow: { \ trail_overflow: { \
@ -221,6 +217,7 @@ global_overflow : { \
*ptd0 = to_visit->d0; \ *ptd0 = to_visit->d0; \
} \ } \
clean_tr(TR0 PASS_REGS); \ clean_tr(TR0 PASS_REGS); \
pop_text_stack(lvl); \
HR = InitialH; \ HR = InitialH; \
LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; \ LOCAL_Error_TYPE = RESOURCE_ERROR_STACK; \
size_t expand = 0L; \ size_t expand = 0L; \
@ -228,7 +225,7 @@ global_overflow : { \
Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil, sizeof(CELL)*(HR-H0)); \ Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil, sizeof(CELL)*(HR-H0)); \
return false;\ return false;\
}\ }\
goto reset;\ goto reset;\
} }
#define CYC_LIST \ #define CYC_LIST \
@ -261,6 +258,13 @@ if (IS_VISIT_MARKER) { \
@brief routine to locate all variables in a term, and its applications */ @brief routine to locate all variables in a term, and its applications */
static Term cyclic_complex_term(CELL *pt0_, CELL *pt0_end_ USES_REGS) { static Term cyclic_complex_term(CELL *pt0_, CELL *pt0_end_ USES_REGS) {
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
WALK_COMPLEX_TERM__(CYC_LIST, CYC_APPL, {}); WALK_COMPLEX_TERM__(CYC_LIST, CYC_APPL, {});
/* leave an empty slot to fill in later */ /* leave an empty slot to fill in later */
END_WALK(); END_WALK();
@ -308,21 +312,22 @@ static Term BREAK_LOOP(CELL d0,struct non_single_struct_t *to_visit ) {
static int cycles_in_complex_term( CELL *pt0_, CELL *pt0_end_ USES_REGS) { static int cycles_in_complex_term( CELL *pt0_, CELL *pt0_end_ USES_REGS) {
CELL *pt0, *pt0_end; CELL *pt0, *pt0_end;
int lvl = push_text_stack();
size_t auxsz = 1024 * sizeof(struct non_single_struct_t); size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0=NULL, *to_visit, *to_visit_max; struct non_single_struct_t *to_visit0, *to_visit, *to_visit_max;
int lvl;
reset:
lvl = push_text_stack();
pt0 = pt0_, pt0_end = pt0_end_;
to_visit0 = Malloc(auxsz);
to_visit= to_visit0;
to_visit_max = to_visit0 + auxsz/sizeof(struct non_single_struct_t);
CELL *InitialH = HR; CELL *InitialH = HR;
tr_fr_ptr TR0 = TR; tr_fr_ptr TR0 = TR;
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { \ if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { \
/* Trail overflow */\ /* Trail overflow */\
goto trail_overflow;\ goto trail_overflow;\
}\ }\
reset:
pt0 = pt0_, pt0_end = pt0_end_;
to_visit0 = Realloc(to_visit0,auxsz);
to_visit= to_visit0;
to_visit_max = to_visit0 + auxsz/sizeof(struct non_single_struct_t);
auxsz *= 2; auxsz *= 2;
int rc = 0; int rc = 0;
CELL *ptf; CELL *ptf;
@ -467,6 +472,12 @@ static Int cycles_in_term(USES_REGS1) /* cyclic_term(+T) */
@brief routine to locate all variables in a term, and its applications */ @brief routine to locate all variables in a term, and its applications */
static bool ground_complex_term(CELL * pt0_, CELL * pt0_end_ USES_REGS) { static bool ground_complex_term(CELL * pt0_, CELL * pt0_end_ USES_REGS) {
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
WALK_COMPLEX_TERM(); WALK_COMPLEX_TERM();
/* leave an empty slot to fill in later */ /* leave an empty slot to fill in later */
@ -515,6 +526,12 @@ static Int ground(USES_REGS1) /* ground(+T) */
static Int var_in_complex_term(CELL *pt0_, CELL *pt0_end_ , static Int var_in_complex_term(CELL *pt0_, CELL *pt0_end_ ,
Term v USES_REGS) { Term v USES_REGS) {
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
WALK_COMPLEX_TERM(); WALK_COMPLEX_TERM();
@ -596,7 +613,14 @@ static Term vars_in_complex_term(CELL *pt0_, CELL *pt0_end_ ,
} }
CELL output = AbsPair(HR); CELL output = AbsPair(HR);
WALK_COMPLEX_TERM(); CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
WALK_COMPLEX_TERM();
/* do or pt2 are unbound */ /* do or pt2 are unbound */
if (HR + 1024 > ASP) { if (HR + 1024 > ASP) {
@ -756,6 +780,12 @@ typedef struct att_rec {
static Term attvars_in_complex_term( static Term attvars_in_complex_term(
CELL *pt0_, CELL *pt0_end_ , Term inp USES_REGS) { CELL *pt0_, CELL *pt0_end_ , Term inp USES_REGS) {
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
CELL output = inp; CELL output = inp;
WALK_COMPLEX_TERM(); WALK_COMPLEX_TERM();
if (IsAttVar(ptd0)) { if (IsAttVar(ptd0)) {
@ -821,27 +851,36 @@ static Int term_attvars(USES_REGS1) /* variables in term t */
*/ */
static Term new_vars_in_complex_term( static Term new_vars_in_complex_term(
CELL *pt0_, CELL *pt0_end_ , Term inp USES_REGS) { CELL *pt0_, CELL *pt0_end_ , Term inp USES_REGS) {
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
Int n=0; Int n=0;
CELL output = TermNil; CELL output = TermNil;
{ Term inp0 = inp;
int lvl = push_text_stack();
while (!IsVarTerm(inp) && IsPairTerm(inp)) { while (!IsVarTerm(inp) && IsPairTerm(inp)) {
Term t = HeadOfTerm(inp); Term t = HeadOfTerm(inp);
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
n++; n++;
TrailTerm(TR++) = t; TrailTerm(TR++) = t;
*VarOfTerm(t) = TermFoundVar; *VarOfTerm(t) = TermFoundVar;
if ((tr_fr_ptr)LOCAL_TrailTop - TR < 1024) { if ((tr_fr_ptr)LOCAL_TrailTop - TR < 1024) {
size_t expand = (tr_fr_ptr)LOCAL_TrailTop - TR;
if (!Yap_growtrail(n * sizeof(tr_fr_ptr *), true)) { clean_tr(TR0 PASS_REGS);
goto trail_overflow; *HR++ = inp0;
} /* Trail overflow */
} if (!Yap_growtrail(expand, false)) {
} Yap_ThrowError(RESOURCE_ERROR_TRAIL, TermNil, expand);
inp = TailOfTerm(inp); }
} inp = *--HR;
pop_text_stack(lvl); continue;
} }
inp = TailOfTerm(inp);
}
}
WALK_COMPLEX_TERM(); WALK_COMPLEX_TERM();
output = MkPairTerm((CELL)ptd0, output); output = MkPairTerm((CELL)ptd0, output);
TrailTerm(TR++) = *ptd0; TrailTerm(TR++) = *ptd0;
@ -904,6 +943,12 @@ static Term vars_within_complex_term(
CELL *pt0_, CELL *pt0_end_, Term inp USES_REGS) { CELL *pt0_, CELL *pt0_end_, Term inp USES_REGS) {
Int n=0; Int n=0;
CELL output = AbsPair(HR); CELL output = AbsPair(HR);
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
while (!IsVarTerm(inp) && IsPairTerm(inp)) { while (!IsVarTerm(inp) && IsPairTerm(inp)) {
Term t = HeadOfTerm(inp); Term t = HeadOfTerm(inp);
@ -1012,6 +1057,12 @@ return Yap_unify(ARG2, t) && Yap_unify(ARG3, out);
static Term non_singletons_in_complex_term(CELL * pt0_, static Term non_singletons_in_complex_term(CELL * pt0_,
CELL * pt0_end_ USES_REGS) { CELL * pt0_end_ USES_REGS) {
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
WALK_COMPLEX_TERM__({}, {}, FOUND_VAR_AGAIN()); WALK_COMPLEX_TERM__({}, {}, FOUND_VAR_AGAIN());
/* do or pt2 are unbound */ /* do or pt2 are unbound */
@ -1080,6 +1131,12 @@ if (singles) { \
static Int numbervars_in_complex_term(CELL * pt0_, CELL * pt0_end_, Int numbv, static Int numbervars_in_complex_term(CELL * pt0_, CELL * pt0_end_, Int numbv,
int singles USES_REGS) { int singles USES_REGS) {
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
WALK_COMPLEX_TERM__({}, {}, {}); WALK_COMPLEX_TERM__({}, {}, {});
@ -1162,6 +1219,12 @@ if (FunctorOfTerm(d0) == FunctorDollarVar) { \
static int max_numbered_var(CELL * pt0_, CELL * pt0_end_, static int max_numbered_var(CELL * pt0_, CELL * pt0_end_,
Int * maxp USES_REGS) { Int * maxp USES_REGS) {
CELL *pt0, *pt0_end;
int lvl;
size_t auxsz = 1024 * sizeof(struct non_single_struct_t);
struct non_single_struct_t *to_visit0, *to_visit,* to_visit_max;
CELL *InitialH = HR;
tr_fr_ptr TR0 = TR;
WALK_COMPLEX_TERM__({}, MAX_NUMBERED, {}); WALK_COMPLEX_TERM__({}, MAX_NUMBERED, {});
END_WALK(); END_WALK();

View File

@ -195,7 +195,8 @@ void *Realloc(void *pt, size_t sz USES_REGS) {
if (!pt) if (!pt)
return Malloc(sz PASS_REGS); return Malloc(sz PASS_REGS);
old--; old--;
sz = ALIGN_BY_TYPE(sz + sizeof(struct mblock), Yap_Max(CELLSIZE,sizeof(struct mblock))); sz = ALIGN_BY_TYPE(sz, Yap_Max(CELLSIZE,sizeof(struct mblock)));
sz += 2*sizeof(struct mblock);
o = realloc(old, sz); o = realloc(old, sz);
if (o->next) { if (o->next) {
o->next->prev = o; o->next->prev = o;

View File

@ -52,14 +52,13 @@ typedef struct non_single_struct_t {
} }
#define def_aux_overflow() \ #define def_aux_overflow() \
aux_overflow:{ \ while (to_visit_max-to_visit0 < 32) { \
size_t d1 = to_visit-to_visit0; \ size_t d1 = to_visit-to_visit0; \
size_t d2 = to_visit_max-to_visit0; \ size_t d2 = to_visit_max-to_visit0; \
to_visit0 = Realloc(to_visit0,(d2+128)*sizeof(struct non_single_struct_t)); \ size_t d3 = Yap_Min(d2+1024, d2 *2); \
to_visit0 = Realloc(to_visit0,d3*sizeof(struct non_single_struct_t)); \
to_visit = to_visit0+d1; \ to_visit = to_visit0+d1; \
to_visit_max = to_visit0+(d2+128); \ to_visit_max = to_visit0+(d3); \
pt0--; \
goto restart; \
} }
#define def_global_overflow() \ #define def_global_overflow() \
@ -152,7 +151,8 @@ clean_complex_tr(tr_fr_ptr TR0 USES_REGS) {
#define expand_stack(S0,SP,SF,TYPE) \ #define expand_stack(S0,SP,SF,TYPE) \
{ size_t sz = SF-S0, used = SP-S0; \ { size_t sz = SF-S0, used = SP-S0; \
S0 = Realloc(S0, (1024+sz)*sizeof(TYPE) PASS_REGS); \ sz += 1024;\
S0 = Realloc(S0, sz*sizeof(TYPE) PASS_REGS); \
SP = S0+used; SF = S0+sz; } SP = S0+used; SF = S0+sz; }
#define MIN_ARENA_SIZE (1048L) #define MIN_ARENA_SIZE (1048L)
@ -207,6 +207,8 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end,
to_visit++; to_visit++;
// move to new list // move to new list
d0 = *headp; d0 = *headp;
if ((ADDR)TR > LOCAL_TrailTop - MIN_ARENA_SIZE)
goto trail_overflow;
TrailedMaBind(headp, AbsPair(HR)); TrailedMaBind(headp, AbsPair(HR));
pt0 = headp; pt0 = headp;
pt0_end = headp + 1; pt0_end = headp + 1;
@ -306,6 +308,8 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end,
if (++to_visit >= to_visit_max-32) { if (++to_visit >= to_visit_max-32) {
expand_stack(to_visit0, to_visit, to_visit_max, struct cp_frame); expand_stack(to_visit0, to_visit, to_visit_max, struct cp_frame);
} }
if ((ADDR)TR > LOCAL_TrailTop - MIN_ARENA_SIZE)
goto trail_overflow;
TrailedMaBind(headp,AbsAppl(HR)); TrailedMaBind(headp,AbsAppl(HR));
ptf = HR; ptf = HR;
*ptf++ = (CELL)f; *ptf++ = (CELL)f;
@ -345,18 +349,14 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end,
} }
to_visit = bp; to_visit = bp;
new = *ptf; new = *ptf;
if (TR > (tr_fr_ptr)LOCAL_TrailTop - 256) { if ((ADDR)TR > LOCAL_TrailTop - MIN_ARENA_SIZE)
/* Trail overflow */ goto trail_overflow;
if (!Yap_growtrail((TR - TR0) * sizeof(tr_fr_ptr *), TRUE)) {
goto trail_overflow;
}
}
TrailedMaBind(ptd0, new); TrailedMaBind(ptd0, new);
ptf++; ptf++;
} else { } else {
/* first time we met this term */ /* first time we met this term */
RESET_VARIABLE(ptf); RESET_VARIABLE(ptf);
if ((ADDR)TR > LOCAL_TrailTop - MIN_ARENA_SIZE) if ((ADDR)TR > LOCAL_TrailTop - MIN_ARENA_SIZE)
goto trail_overflow; goto trail_overflow;
TrailedMaBind(ptd0, (CELL)ptf); TrailedMaBind(ptd0, (CELL)ptf);
ptf++; ptf++;

View File

@ -252,10 +252,10 @@ YAPStringTerm::YAPStringTerm(wchar_t *s, size_t len)
YAPApplTerm::YAPApplTerm(YAPFunctor f, YAPTerm ts[]) { YAPApplTerm::YAPApplTerm(YAPFunctor f, YAPTerm ts[]) {
BACKUP_H(); BACKUP_H();
arity_t arity = ArityOfFunctor(f.f); arity_t arity = ArityOfFunctor(f.f);
Term o = AbsAppl(HR); Term o = Yap_MkNewApplTerm(f.f, arity);
*HR++ = (CELL)f.f; Term *tt = RepAppl(o) + 1;
for (arity_t i = 0; i < arity; i++) for (arity_t i = 0; i < arity; i++)
*HR++ = ts[i].term(); tt[i] = ts[i].term();
mk(o); mk(o);
RECOVER_H(); RECOVER_H();
} }
@ -586,18 +586,18 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) {
q.p = P; q.p = P;
q.cp = CP; q.cp = CP;
q.b0 = LCL0-CellPtr(B);
q.env0 = LCL0-ENV;
for (arity_t i = 0; i < arity; i++) for (arity_t i = 0; i < arity; i++)
XREGS[i + 1] = ts[i].term(); XREGS[i + 1] = ts[i].term();
// allow Prolog style exceotion handling // allow Prolog style exceotion handling
// don't forget, on success these bindings will still be there); // don't forget, on success these bindings will still be there);
result = YAP_LeaveGoal(true, &q); result = YAP_EnterGoal(ap.ap, nullptr, &q);
YAP_LeaveGoal(result, &q);
YAPCatchError(); YAPCatchError();
Yap_CloseHandles(q.CurSlot);
pop_text_stack(q.lvl + 1);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return result; return result;
} }
@ -611,10 +611,48 @@ bool YAPEngine::mgoal(Term t, Term tmod, bool release) {
// _save = PyEval_SaveThread(); // _save = PyEval_SaveThread();
#endif #endif
CACHE_REGS CACHE_REGS
YAP_dogoalinfo q;
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
bool rc = YAP_RunGoalOnce(t); Term *ts = nullptr;
q.CurSlot = Yap_StartSlots();
q.p = P;
q.cp = CP;
Int oenv = LCL0-ENV;
Int oB = LCL0-CellPtr(B);
Term omod = CurrentModule;
PredEntry *ap = nullptr;
if (IsStringTerm(tmod))
tmod = MkAtomTerm(Yap_LookupAtom(StringOfTerm(tmod)));
ap = Yap_get_pred(t, tmod, "C++");
if (ap == nullptr ||
ap->OpcodeOfPred == UNDEF_OPCODE) {
ap = rewriteUndefEngineQuery(ap, t, tmod);
}
if (IsApplTerm(t))
ts = RepAppl(t) + 1;
else if (IsPairTerm(t))
ts = RepPair(t);
/* legal ap */
arity_t arity = ap->ArityOfPE;
for (arity_t i = 0; i < arity; i++) {
XREGS[i + 1] = ts[i];
}
ts = nullptr;
bool result;
// allow Prolog style exception handling
// don't forget, on success these guys may create slots
//__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec ");
result = (bool)YAP_EnterGoal(ap, nullptr, &q);
// std::cerr << "mgoal " << YAPTerm(tmod).text() << ":" << YAPTerm(t).text() << "\n
YAP_LeaveGoal(result && !release, &q);
ENV = LCL0-oenv;
B = (choiceptr)(LCL0-oB);
CurrentModule = LOCAL_SourceModule = omod;
// PyEval_RestoreThread(_save);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
return rc; return result;
} }
/** /**
* called when a query must be terminated and its state fully recovered, * called when a query must be terminated and its state fully recovered,
@ -623,59 +661,74 @@ bool YAPEngine::mgoal(Term t, Term tmod, bool release) {
void YAPEngine::release() { void YAPEngine::release() {
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
YAP_LeaveGoal(FALSE, &q); // YAP_LeaveGoal(FALSE, &q);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
} }
Term YAPEngine::fun(Term t) { Term YAPEngine::fun(Term t) {
CACHE_REGS CACHE_REGS
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
YAP_dogoalinfo q;
Term tmod = Yap_CurrentModule(), *ts = nullptr; Term tmod = Yap_CurrentModule(), *ts = nullptr;
PredEntry *ap;
arity_t arity; arity_t arity;
Functor f; Functor f;
Atom name; Atom name;
q.CurSlot = Yap_StartSlots();
q.p = P;
q.cp = CP;
yhandle_t yt = Yap_NewHandles(1); Int oenv = LCL0-ENV;
Int oB = LCL0-CellPtr(B);
if (IsApplTerm(t)) { if (IsApplTerm(t)) {
ts = RepAppl(t) + 1; ts = RepAppl(t) + 1;
f = (Functor)ts[-1]; f = (Functor)ts[-1];
name = NameOfFunctor(f); name = NameOfFunctor(f);
arity = ArityOfFunctor(f); arity = ArityOfFunctor(f);
t = AbsAppl(HR); for (arity_t i = 0; i < arity; i++)
HR[0] = (CELL)Yap_MkFunctor(name, arity+1); XREGS[i + 1] = ts[i];
for (arity_t i = 0; i < arity; i++) {
HR[i + 1] = ts[i];
}
HR += (arity+2);
arity++;
} else if (IsAtomTerm(t)) { } else if (IsAtomTerm(t)) {
name = AtomOfTerm(t); name = AtomOfTerm(t);
t = AbsAppl(HR); f = nullptr;
HR[0] = (CELL)Yap_MkFunctor(name, 1); arity = 0;
HR += 2;
arity = 1;
} else if (IsPairTerm(t)) { } else if (IsPairTerm(t)) {
HR[0] = (CELL)Yap_MkFunctor(AtomDot, 3); XREGS[1] = ts[0];
HR[1] = ts[0]; XREGS[2] = ts[1];
HR[2] = ts[1]; arity = 2;
HR += 4; name = AtomDot;
arity = 3; f = FunctorDot;
} else { } else {
throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, t, 0); throw YAPError(SOURCE(), TYPE_ERROR_CALLABLE, t, 0);
return 0L; return 0L;
} }
RESET_VARIABLE(HR-1); Term ot = XREGS[arity + 1] = MkVarTerm();
yt = Yap_InitHandle(t); yhandle_t h = Yap_InitHandle(ot);
CACHE_REGS arity++;
BACKUP_MACHINE_REGS(); HR += arity;
bool rc = YAP_RunGoalOnce(t); f = Yap_MkFunctor(name, arity);
Term ot; ap = (PredEntry *)(PredPropByFunc(f, tmod));
if (rc) if (ap == nullptr || ap->OpcodeOfPred == UNDEF_OPCODE) {
ot = ArgOfTerm(arity,Yap_GetFromHandle(yt)); Term g = (Yap_MkApplTerm(f, arity, ts));
else ap = rewriteUndefEngineQuery(ap, g, (ap->ModuleOfPred));
ot = TermNone; }
RECOVER_MACHINE_REGS(); // make sure this is safe
return ot; // allow Prolog style exception handling
//__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec ");
bool result = (bool)YAP_EnterGoal(ap, nullptr, &q);
if (result)
ot = Yap_GetFromHandle(h);
else
ot = TermNone;
YAPCatchError();
{
YAP_LeaveGoal(result, &q);
ENV = LCL0-oenv;
B = (choiceptr)(LCL0-oB);
// PyEval_RestoreThread(_save);
RECOVER_MACHINE_REGS();
return ot;
}
} }
YAPQuery::YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm ts[]) YAPQuery::YAPQuery(YAPFunctor f, YAPTerm mod, YAPTerm ts[])
@ -760,6 +813,9 @@ bool YAPQuery::next() {
CACHE_REGS CACHE_REGS
bool result = false; bool result = false;
// std::cerr << "next " << YAPTerm(goal).text() << "\n"; // std::cerr << "next " << YAPTerm(goal).text() << "\n";
q_h.CurSlot = Yap_StartSlots();
q_h.p = P;
q_h.cp = CP;
sigjmp_buf buf, *oldp = LOCAL_RestartEnv; sigjmp_buf buf, *oldp = LOCAL_RestartEnv;
e = nullptr; e = nullptr;
@ -821,7 +877,7 @@ bool YAPQuery::deterministic() {
BACKUP_MACHINE_REGS(); BACKUP_MACHINE_REGS();
if (!q_open || q_state == 0) if (!q_open || q_state == 0)
return false; return false;
choiceptr myB = (choiceptr)(LCL0 - q_h.b_top); choiceptr myB = (choiceptr)(LCL0 - q_h.b_entry);
return (B >= myB); return (B >= myB);
RECOVER_MACHINE_REGS(); RECOVER_MACHINE_REGS();
} }
@ -1087,13 +1143,15 @@ std::stringstream s;
void YAPEngine::reSet() { void YAPEngine::reSet() {
/* ignore flags for now */ /* ignore flags for now */
if (B && B->cp_b && B->cp_ap != NOCODE) if (B && B->cp_b && B->cp_ap != NOCODE)
YAP_LeaveGoal(false, &q); // YAP_LeaveGoal(false, &q);
LOCAL_ActiveError->errorNo = YAP_NO_ERROR; LOCAL_ActiveError->errorNo = YAP_NO_ERROR;
if (LOCAL_CommittedError) { if (LOCAL_CommittedError) {
LOCAL_CommittedError->errorNo = YAP_NO_ERROR; LOCAL_CommittedError->errorNo = YAP_NO_ERROR;
free(LOCAL_CommittedError); free(LOCAL_CommittedError);
LOCAL_CommittedError = NULL; LOCAL_CommittedError = NULL;
} }
pop_text_stack(0);
LOCAL_CurSlot = 0;
} }
Term YAPEngine::top_level(std::string s) { Term YAPEngine::top_level(std::string s) {

View File

@ -39,7 +39,6 @@ class X_API YAPQuery : public YAPPredicate {
bool q_open; bool q_open;
int q_state; int q_state;
yhandle_t q_handles; yhandle_t q_handles;
struct yami *q_p, *q_cp;
int q_flags; int q_flags;
YAP_dogoalinfo q_h; YAP_dogoalinfo q_h;
YAPPairTerm names; YAPPairTerm names;
@ -54,10 +53,10 @@ class X_API YAPQuery : public YAPPredicate {
q_state = 0; q_state = 0;
q_flags = true; // PL_Q_PASS_EXCEPTION; q_flags = true; // PL_Q_PASS_EXCEPTION;
q_p = P; q_h.p = P;
q_cp = CP; q_h.cp = CP;
// make sure this is safe // make sure this is safe
q_handles = LOCAL_CurSlot; q_h.CurSlot = LOCAL_CurSlot;
}; };
void openQuery(); void openQuery();
@ -321,7 +320,6 @@ private:
YAPCallback *_callback; YAPCallback *_callback;
YAPError yerror; YAPError yerror;
void doInit(YAP_file_type_t BootMode, YAPEngineArgs *cargs); void doInit(YAP_file_type_t BootMode, YAPEngineArgs *cargs);
YAP_dogoalinfo q;
YAPError e; YAPError e;
PredEntry *rewriteUndefEngineQuery(PredEntry *ap, Term &t, Term tmod); PredEntry *rewriteUndefEngineQuery(PredEntry *ap, Term &t, Term tmod);

View File

@ -681,8 +681,9 @@ CalculateStackGap( USES_REGS1 )
#define SET_ASP(Y,S) SET_ASP__(Y,S PASS_REGS) #define SET_ASP(Y,S) SET_ASP__(Y,S PASS_REGS)
static inline INLINE_ONLY void SET_ASP__(CELL *yreg, Int sz USES_REGS);
void SET_ASP__(CELL *yreg, Int sz USES_REGS) {
INLINE_ONLY void SET_ASP__(CELL *yreg, Int sz USES_REGS) {
ASP = (CELL *) (((char *) yreg) + sz); ASP = (CELL *) (((char *) yreg) + sz);
if (ASP > (CELL *)PROTECT_FROZEN_B(B)) if (ASP > (CELL *)PROTECT_FROZEN_B(B))
ASP = (CELL *)PROTECT_FROZEN_B(B); ASP = (CELL *)PROTECT_FROZEN_B(B);

View File

@ -91,7 +91,6 @@ typedef YAP_Term Term;
#define CellSize sizeof(CELL) #define CellSize sizeof(CELL)
#define SmallSize sizeof(SMALLUNSGN) #define SmallSize sizeof(SMALLUNSGN)
typedef YAP_Int Int;
typedef YAP_Float Float; typedef YAP_Float Float;
typedef YAP_handle_t yhandle_t; typedef YAP_handle_t yhandle_t;

View File

@ -46,22 +46,31 @@ extern const void *MallocExportAsRO(const void *blk);
/* Character types for tokenizer and write.c */ /* Character types for tokenizer and write.c */
extern int AllocLevel(void); extern int AllocLevel(void);
#if 0
#define push_text_stack() \ #define push_text_stack() \
(/* fprintf(stderr, " + *** %d %s:%s:%d\n", AllocLevel(),*/ \ ( fprintf(stderr, " + *** %d %s:%s:%d\n", AllocLevel(), \
/* __FILE__, __FUNCTION__, __LINE__), */ \ __FILE__, __FUNCTION__, __LINE__), \
push_text_stack__(PASS_REGS1)) push_text_stack__(PASS_REGS1))
extern int push_text_stack__(USES_REGS1);
#define pop_text_stack(lvl) \ #define pop_text_stack(lvl) \
(/* fprintf(stderr, " - *** %d %s:%s:%d\n", AllocLevel(), __FILE__,*/ \ ( fprintf(stderr, " - *** %d %s:%s:%d\n", AllocLevel(), __FILE__, \
/* __FUNCTION__, __LINE__), */ \ __FUNCTION__, __LINE__), \
pop_text_stack__(lvl)) pop_text_stack__(lvl PASS_REGS))
#define pop_output_text_stack(lvl,p) \
(fprintf(stderr, "-- *** %d %s:%s:%d\n", AllocLevel(), __FILE__, \
__FUNCTION__, __LINE__), \
pop_output_text_stack__(lvl,p))
#else
#define push_text_stack() push_text_stack__(PASS_REGS1)
#define pop_text_stack(lvl) pop_text_stack__(lvl PASS_REGS)
#define pop_output_text_stack(lvl,p) pop_output_text_stack__(lvl,p PASS_REGS)
#endif
extern int push_text_stack__(USES_REGS1);
extern int pop_text_stack__(int lvl USES_REGS); extern int pop_text_stack__(int lvl USES_REGS);
#define pop_output_text_stack(lvl,p) \
(/*fprintf(stderr, "-- *** %d %s:%s:%d\n", AllocLevel(), __FILE__,*/ \
/* __FUNCTION__, __LINE__),*/ \
pop_output_text_stack__(lvl,p))
extern void *pop_output_text_stack__(int lvl, const void *ox USES_REGS); extern void *pop_output_text_stack__(int lvl, const void *ox USES_REGS);
/****************** character definition table **************************/ /****************** character definition table **************************/

View File

@ -203,12 +203,12 @@ extern void Yap_fail_all(choiceptr bb USES_REGS);
extern Term Yap_ExecuteCallMetaCall(Term,Term); extern Term Yap_ExecuteCallMetaCall(Term,Term);
extern void Yap_InitExecFs(void); extern void Yap_InitExecFs(void);
extern bool Yap_JumpToEnv(void); extern bool Yap_JumpToEnv(void);
extern Term Yap_RunTopGoal(Term, struct goal_info *, bool); extern Term Yap_RunTopGoal(Term, bool);
extern bool Yap_execute_goal(Term, int, Term, bool); extern bool Yap_execute_goal(Term, int, Term, bool);
extern bool Yap_exec_absmi(bool, yap_reset_t); extern bool Yap_exec_absmi(bool, yap_reset_t);
extern void Yap_trust_last(void); extern void Yap_trust_last(void);
extern void Yap_closeGoal(bool out, yamop *saved_p, yamop * saved_cp, Int saved_e, Int saved_b, yhandle_t hdl, bool pass_ex);
extern void Yap_PrepGoal(UInt, CELL *, struct goal_info * USES_REGS); extern void Yap_PrepGoal(UInt, CELL *, choiceptr USES_REGS);
extern bool Yap_execute_pred(struct pred_entry *ppe, CELL *pt, extern bool Yap_execute_pred(struct pred_entry *ppe, CELL *pt,
bool pass_exception USES_REGS); bool pass_exception USES_REGS);
extern int Yap_dogc(int extra_args, Term *tp USES_REGS); extern int Yap_dogc(int extra_args, Term *tp USES_REGS);
@ -247,7 +247,7 @@ extern Term Yap_SaveTerm(Term);
extern Term Yap_SetGlobalVal(Atom, Term); extern Term Yap_SetGlobalVal(Atom, Term);
extern Term Yap_GetGlobal(Atom); extern Term Yap_GetGlobal(Atom);
extern Int Yap_DeleteGlobal(Atom); extern Int Yap_DeleteGlobal(Atom);
extern void Yap_AllocateDefaultArena(size_t gsize, int wid); extern void Yap_AllocateDefaultArena(size_t gsize, int wid, void *cs);
extern CELL *Yap_ArenaLimit(Term arena); extern CELL *Yap_ArenaLimit(Term arena);
/* grow.c */ /* grow.c */

View File

@ -2398,6 +2398,7 @@ Int (*Yap_traced_absmi)(void);
extern JIT_Compiler *J; extern JIT_Compiler *J;
#endif #endif
extern NativeContext *NativeArea; extern NativeContext *NativeArea;
extern IntermediatecodeContext *IntermediatecodeArea; extern IntermediatecodeContext *IntermediatecodeArea;
@ -2421,7 +2422,7 @@ extern yamop *headoftrace;
#ifdef SHADOW_S #ifdef SHADOW_S
#define PROCESS_INT(F, C) \ #define PROCESS_INT(F, C) \
BEGD(d0); \ BEGD(d0); \
Yap_REGS.S_ = SREG; \ Yap_REGSS_ = SREG; \
saveregs(); \ saveregs(); \
d0 = F(PASS_REGS1); \ d0 = F(PASS_REGS1); \
setregs(); \ setregs(); \
@ -2444,8 +2445,8 @@ extern yamop *headoftrace;
FAIL(); \ FAIL(); \
if (d0 == 2) \ if (d0 == 2) \
goto C; \ goto C; \
JMPNext(); \ JMPNext();\
ENDD(d0); ENDD(d0);
#endif #endif
#define Yap_AsmError(e, d) \ #define Yap_AsmError(e, d) \

View File

@ -577,4 +577,5 @@ static inline int do_cut(int i) {
#define cut_fail() return do_cut(FALSE) #define cut_fail() return do_cut(FALSE)
#endif #endif

View File

@ -465,6 +465,8 @@ extern yap_error_descriptor_t *Yap_bug_location(yap_error_descriptor_t *t, yamop
extern yap_error_descriptor_t *Yap_pc_add_location(yap_error_descriptor_t *t, void *p, void *b_ptr, void *env); extern yap_error_descriptor_t *Yap_pc_add_location(yap_error_descriptor_t *t, void *p, void *b_ptr, void *env);
extern yap_error_descriptor_t * Yap_env_add_location(yap_error_descriptor_t *t, void *p, void *b_ptr, void *env, YAP_Int ignore_first); extern yap_error_descriptor_t * Yap_env_add_location(yap_error_descriptor_t *t, void *p, void *b_ptr, void *env, YAP_Int ignore_first);
void Yap_split_megaclause(PredEntry *ap);
#if LOW_PROF #if LOW_PROF
void Yap_InformOfRemoval(void *); void Yap_InformOfRemoval(void *);
void Yap_dump_code_area_for_profiler(void); void Yap_dump_code_area_for_profiler(void);

523
H/heap.h
View File

@ -1,523 +0,0 @@
//
// File defining fields in the Yap_heap_codes global structure
//
// these fields used to spread all over the place, because they must be used in
// 4 ways:
// - they must be defined somewhere
// - they have an #ifdef to get a shorter name
// - they must be initialised somewhere
// - they must be restorable and collectable (from the atom gc).
//
//
// The defs include 4+ components:
// Type
// name in structured
// global name
// init code and restore code (optional)
//
//
//
// MkAT\(MkAtomTerm) cvts from a predefined atom to a term
// MkPred constructs a pr%ed_entry
// MkOp gets an opcode
// void does nothing
// =VALUE inits as VALUE
// Init... sets up call to InitFunc
// Restore... sets up call to RestoreFunc
// HM refers to standard field
// HI refers to field that does not need restore
// H_R refers to field that does not need init, but needs restore
// HSPACE refers to a field without init not recovery
// HMLOCK refers to a lock
// HRWLOCK refers to a rwlock
// HOPCODE refers to a opcode
// HOPCODE refers to a field initialized/restored with a proceeding
/* memory management */
HSPACE(struct malloc_state *, Yap_av)
#if USE_DL_MALLOC
HSPACE(struct memory_hole, Yap_MemoryHoles)
HSPACE(UInt, Yap_NOfMemoryHoles)
#if defined(YAPOR) || defined(THREADS)
HMLOCK(lockvar, DLMallocLock)
#endif
#endif
#if USE_DL_MALLOC || (USE_SYSTEM_MALLOC && HAVE_MALLINFO)
#ifndef HeapUsed
#define HeapUsed Yap_givemallinfo()
#endif
HSPACE(Int, NotHeapUsed)
#else
HSPACE(Int, HeapUsed)
#endif
HSPACE(Int, HeapMax)
HSPACE(ADDR, HeapTop)
HSPACE(ADDR, HeapLim)
HSPACE(struct FREEB *, FreeBlocks)
#if defined(YAPOR) || defined(THREADS)
HMLOCK(lockvar, FreeBlocksLock)
HMLOCK(lockvar, HeapUsedLock)
HMLOCK(lockvar, HeapTopLock)
HI(int, HeapTopOwner, -1)
#endif
HI(UInt, MaxStack, 0)
HI(UInt, MaxTrail, 0)
/* execution info */
/* OPCODE REVERSE TABLE, needed to recover op tables */
#if USE_THREADED_CODE
HM(op_entry, OP_RTABLE, NULL, OpRTableAdjust)
#endif
/* popular opcodes */
HMOPCODE(EXECUTE_CPRED_OP_CODE, _execute_cpred)
HMOPCODE(EXPAND_OP_CODE, _expand_index)
HMOPCODE(FAIL_OPCODE, _op_fail)
HMOPCODE(INDEX_OPCODE, _index_pred)
HMOPCODE(LOCKPRED_OPCODE, _lock_pred)
HMOPCODE(ORLAST_OPCODE, _or_last)
HMOPCODE(UNDEF_OPCODE, _undef_p)
HMOPCODE(RETRY_USERC_OPCODE, _retry_userc)
HMOPCODE(EXECUTE_CPRED_OPCODE, _execute_cpred)
/* atom tables */
HSPACE(UInt, NOfAtoms)
HSPACE(UInt, AtomHashTableSize)
HSPACE(UInt, WideAtomHashTableSize)
HSPACE(UInt, NOfWideAtoms)
HPROC(AtomHashEntry, INVISIBLECHAIN, InitInvisibleAtoms(),
RestoreInvisibleAtoms())
HPROC(AtomHashEntry *, WideHashChain, InitWideAtoms(), RestoreWideAtoms())
HPROC(AtomHashEntry *, HashChain, InitAtoms(), RestoreAtoms())
#if __INIT_C__
/* use atom defs here */
#include "iatoms.h"
#endif
#ifdef EUROTRA
HATOMT(TermDollarU, AtomDollarU)
#endif
// modules
HATOMT(USER_MODULE, AtomUser)
HATOMT(IDB_MODULE, AtomIDB)
HATOMT(ATTRIBUTES_MODULE, AtomAttributes)
HATOMT(CHARSIO_MODULE, AtomCharsio)
HATOMT(CHTYPE_MODULE, AtomChType)
HATOMT(TERMS_MODULE, AtomTerms)
HATOMT(SYSTEM_MODULE, AtomSystem)
HATOMT(READUTIL_MODULE, AtomReadutil)
HATOMT(HACKS_MODULE, AtomYapHacks)
HATOMT(ARG_MODULE, AtomArg)
HATOMT(GLOBALS_MODULE, AtomNb)
HATOMT(SWI_MODULE, AtomSwi)
HATOMT(DBLOAD_MODULE, AtomDBLoad)
HATOMT(RANGE_MODULE, AtomRange)
HATOMT(ERROR_MODULE, AtomError)
//
// Module list
//
HM(struct mod_entry *, CurrentModules, NULL, ModEntryPtrAdjust)
// make sure we have the modules set at this point.
// don't actually want to define a field
#if __INIT_C__
Yap_InitModules();
#endif
// hidden predicates
HM(Prop, HIDDEN_PREDICATES, NULL, RestoreHiddenPredicates())
// make sure we have the streams set at this point.
// don't actually want to define a field
#if __INIT_C__
Yap_InitPlIO();
#endif
HSPACE(union flagTerm *, GFlags)
HM(UInt, GLOBAL_flagCount, Yap_InitFlags(true), RestoreFlags(GLOBAL_flagCount))
/* Anderson's JIT */
HM(yap_exec_mode, Yap_ExecutionMode, INTERPRETED, rv_void)
/* The Predicate Hash Table: fast access to predicates. */
HPROC(struct pred_entry **, PredHash, InitPredHash(), RestorePredHash())
#if defined(YAPOR) || defined(THREADS)
HRWLOCK(rwlock_t, PredHashRWLock)
#endif
HSPACE(UInt, PredsInHashTable)
HSPACE(UInt, PredHashTableSize)
/* Well-Known Predicates */
HAROP(CreepCode, AtomCreep, 1, PROLOG_MODULE)
HAROP(UndefCode, AtomUndefp, 2, PROLOG_MODULE)
HAROP(SpyCode, AtomSpy, 1, PROLOG_MODULE)
HAROP(PredFail, AtomFail, 0, PROLOG_MODULE)
HAROP(PredTrue, AtomTrue, 0, PROLOG_MODULE)
#ifdef COROUTINING
HAROP(WakeUpCode, AtomWakeUpGoal, 2, PROLOG_MODULE)
#endif
HFOP(PredGoalExpansion, FunctorGoalExpansion, USER_MODULE)
HFOP(PredMetaCall, FunctorMetaCall, PROLOG_MODULE)
HFOP(PredTraceMetaCall, FunctorTraceMetaCall, PROLOG_MODULE)
HFOP(PredDollarCatch, FunctorCatch, PROLOG_MODULE)
HFOP(PredRecordedWithKey, FunctorRecordedWithKey, PROLOG_MODULE)
HFOP(PredLogUpdClause, FunctorDoLogUpdClause, PROLOG_MODULE)
HFOP(PredLogUpdClauseErase, FunctorDoLogUpdClauseErase, PROLOG_MODULE)
HFOP(PredLogUpdClause0, FunctorDoLogUpdClause, PROLOG_MODULE)
HFOP(PredStaticClause, FunctorDoStaticClause, PROLOG_MODULE)
HFOP(PredThrow, FunctorThrow, PROLOG_MODULE)
HFOP(PredHandleThrow, FunctorHandleThrow, PROLOG_MODULE)
HFOP(PredIs, FunctorIs, PROLOG_MODULE)
HFOP(PredSafeCallCleanup, FunctorSafeCallCleanup, PROLOG_MODULE)
HFOP(PredRestoreRegs, FunctorRestoreRegs, PROLOG_MODULE)
HFOP(PredCommentHook, FunctorCommentHook, PROLOG_MODULE)
#ifdef YAPOR
HAROP(PredGetwork, AtomGetwork, 0, PROLOG_MODULE)
HFOP(PredProcedure, MkLogPred, FunctorProcedure, PROLOG_MODULE)
#endif /* YAPOR */
/* low-level tracer */
#ifdef LOW_LEVEL_TRACER
HSPACE(bool, Yap_do_low_level_trace)
#if defined(YAPOR) || defined(THREADS)
HMLOCK(Yap_low_level_trace_lock)
#endif
#endif
/* code management info */
HI(UInt, Yap_ClauseSpace, 0)
HI(UInt, Yap_IndexSpace_Tree, 0)
HI(UInt, Yap_IndexSpace_EXT, 0)
HI(UInt, Yap_IndexSpace_SW, 0)
HI(UInt, Yap_LUClauseSpace, 0)
HI(UInt, Yap_LUIndexSpace_Tree, 0)
HI(UInt, Yap_LUIndexSpace_CP, 0)
HI(UInt, Yap_LUIndexSpace_EXT, 0)
HI(UInt, Yap_LUIndexSpace_SW, 0)
/* static code: may be shared by many predicate or may be used for
* meta-execution */
HYOP(5, COMMA_CODE, _op_fail)
HYOP(1, DUMMYCODE, _op_fail)
HYOP(1, FAILCODE, _op_fail)
HYOP(1, NOCODE, _Nstop)
#ifdef BEAM
HYOP(beam_retry_code, 1, BEAM_RETRY_CODE, _beam_retry_code)
#endif /* BEAM */
HENVYOP(2, ENV_FOR_TRUSTFAIL, _trust_fail, PredFail, TRUSTFAILCODE)
HSPACE(yamop *, TRUSTFAILCODE)
HENVYOP(2, ENV_FOR_YESCODE, _Ystop, PredFail, YESCODE)
HSPACE(yamop *, YESCODE)
HCPYOP(1, RTRYCODE, _retry_and_mark, PredFail)
#ifdef BEAM
HCPYOP(1, BEAM_RETRY_CODE, PredFail)
#endif
#ifdef YAPOR
HCPYOP(1, GETWORK, _getwork, PredGetwork)
HCPYOP(1, GETWORK_SEQ, _getwork_seq, PredGetworkSeq)
HCPYOP(1, GETWORK_FIRST_TIME, _getwork_first_time, PredGetworkFirstTime)
#endif /* YAPOR */
#ifdef TABLING
HCPYOP(1, LOAD_ANSWER, _table_load_answer, PredFail)
HCPYOP(1, TRY_ANSWER, _table_try_answer, PredFail)
HCPYOP(1, ANSWER_RESOLUTION, _table_load_answer, PredFail)
HCPYOP(1, COMPLETION, _table_completion, PredFail)
#ifdef THREADS_CONSUMER_SHARING
HCPYOP(1, ANSWER_RESOLUTION_COMPLETION, _table_answer_resolution_completion,
PredFail)
#endif /* THREADS_CONSUMER_SHARING */
#endif /* TABLING */
/* */
/* PREG just before we enter $spy. We use that to find out the clause which
*/
/* was calling the debugged goal. */
/* */
HM(struct yami *, P_before_spy, NULL, PtoOpAdjust(P_before_spy))
/* support recorded_k */
HM(struct yami *, RETRY_C_RECORDEDP_CODE, NULL,
PtoOpAdjust(RETRY_C_RECORDEDP_CODE))
HM(struct yami *, RETRY_C_RECORDED_K_CODE, NULL,
PtoOpAdjust(RETRY_C_RECORDED__CODE))
/* compiler flags */
HI(bool, PROFILING, false)
HI(bool, CALL_COUNTING, false)
HI(bool, optimizer_on, true)
HI(bool, compile_mode, false)
HI(bool, profiling, false)
HI(bool, call_counting, false)
/********* whether we should try to compile array references ******************/
HI(bool, compile_arrays, false)
/* DBTerms: pre-compiled ground terms */
#if defined(YAPOR) || defined(THREADS)
HMLOCK(lockvar, DBTermsListLock)
#endif
HM(struct dbterm_list *, DBTermsList, NULL, RestoreDBTermsList())
/* JITI support */
HI(yamop, ExpandClausesFirst, NULL)
HM(yamop, ExpandClausesLast, NULL, RestoreExpandList())
HI(UInt, Yap_ExpandClauses, 0)
#if defined(YAPOR) || defined(THREADS)
HMLOCK(lockvar, ExpandClausesListLock)
HMLOCK(lockvar, OpListLock)
#endif
/* instrumentation */
#ifdef DEBUG
HI(UInt, Yap_NewCps, 0L)
HI(UInt, Yap_LiveCps, 0L)
HI(UInt, Yap_DirtyCps, 0L)
HI(UInt, Yap_FreedCps, 0L)
#endif
HI(UInt, Yap_expand_clauses_sz, 0L)
/* UDI support */
H_R(struct udi_info *, UdiControlBlocks, RestoreUdiControlBlocks())
/* data-base statistics */
/* system boots in compile mode */
HI(Int, STATIC_PREDICATES_MARKED, false)
/* Internal Database */
HM(Prop, INT_KEYS, NULL, RestoreIntKeys())
HM(Prop, INT_LU_KEYS, NULL, RestoreIntLUKeys())
HM(Prop, INT_BB_KEYS, NULL, RestoreIntBBKeys())
/* Internal Database Statistics */
HI(UInt, INT_KEYS_SIZE, INT_KEYS_DEFAULT_SIZE)
HI(UInt, INT_KEYS_TIMESTAMP, 0L)
HI(UInt, INT_BB_KEYS_SIZE, INT_KEYS_DEFAULT_SIZE)
/* Internal Data-Base Control */
HI(int, UPDATE_MODE, UPDATE_MODE_LOGICAL)
/* nasty IDB stuff */
HPROC(struct DB_STRUCT *, DBErasedMarker, InitDBErasedMarker(),
RestoreDBErasedMarker())
HPROC(struct logic_upd_clause *, LogDBErasedMarker, InitLogDBErasedMarker(),
RestoreLogDBErasedMarker())
/* Dead clauses and IDB entries */
H_R(struct static_clause *, DeadStaticClauses, RestoreDeadStaticClauses())
H_R(struct static_mega_clause *, DeadMegaClauses, RestoreDeadMegaClauses())
H_R(struct static_index *, DeadStaticIndices, RestoreDeadStaticIndices())
H_R(struct logic_upd_clause *, DBErasedList, RestoreDBErasedList())
H_R(struct logic_upd_index *, DBErasedIList, RestoreDBErasedIList())
#if defined(YAPOR) || defined(THREADS)
HMLOCK(lockvar, DeadStaticClausesLock)
HMLOCK(lockvar, DeadMegaClausesLock)
HMLOCK(lockvar, DeadStaticIndicesLock)
#endif
#ifdef COROUTINING
/* number of attribute modules */
HI(int, NUM_OF_ATTS, 1)
/* initialised by memory allocator */
HI(UInt, Yap_AttsSize, 0)
#endif
/* Operators */
HM(struct operator_entry *, OpList, NULL, OpListAdjust)
/* foreign code loaded */
HM(struct ForeignLoadItem *, ForeignCodeLoaded, NULL, RestoreForeignCode())
HI(ADDR, ForeignCodeBase, NULL)
HI(ADDR, ForeignCodeTop, NULL)
HI(ADDR, ForeignCodeMax, NULL)
/* recorded terms */
HM(struct record_list *, Yap_Records, NULL, RestoreYapRecords())
/* SWI atoms and functors */
HPROC(struct atom_entry *, SWI_Atoms, InitSWIAtoms(), RestoreSWIAtoms())
HSPACE(struct functor_entry *, SWI_Functors)
HSPACEN(struct swi_reverse_hash, N_SWI_HASH, SWI_ReverseHash)
/* integer access to atoms */
HSPACE(Int, AtomTranslations)
HSPACE(Int, MaxAtomTranslations)
// initialization: tell whether the system has been initialised and by whom.
HI(int, Initialised, false)
HI(int, InitialisedFromPL, false)
HI(int, PL_Argc, 0)
HI(char **, PL_Argv, NULL)
HI(bool, FAST_BOOT_FLAG, false)
// halt hooks
HI(struct halt_hook *, HaltHooks, NULL)
HI(fptr_t, JIT_finalizer, NULL)
// stack overflow expansion/gc control
HI(int, AllowLocalExpansion, true)
HI(int, AllowGlobalExpansion, true)
HI(int, AllowTrailExpansion, true)
HI(UInt, SizeOfOverflow, 0)
// amount of space recovered in all garbage collections
HI(UInt, AGcThreshold, 10000)
HI(Agc_hook, AGCHook, NULL)
/* integer access to functors */
HSPACE(Int, FunctorTranslations)
HSPACE(Int, MaxFunctorTranslations)
HPROCN(Atom, MAX_EMPTY_WAKEUPS, EmptyWakeups, InitEmptyWakeups(),
RestoreEmptyWakeups())
HSPACE(int, MaxEmptyWakeups)
/* SWI blobs */
HM(struct YAP_blob_t *, BlobTypes, NULL, RestoreBlobTypes())
HM(struct AtomEntryStruct *, Blobs, NULL, RestoreBlobs())
HI(UInt, NOfBlobs, 0)
HI(UInt, NOfBlobsMax, 256)
#if defined(YAPOR) || defined(THREADS)
HMLOCK(lockvar blobs_lock, Blobs_Lock)
#endif
#if __ANDROID__
// no need to perform initialization, it is done before we start the Prolog
// engine.
HI(struct AAssetManager *, assetManager, NULL)
HI(char *, AssetsWD, NULL)
#endif
/* multi-thread support */
#if THREADS
/* number of threads and processes in system */
HI(UInt, NOfThreads, 1)
/* number of threads created since start */
HI(UInt, NOfThreadsCreated, 1)
/* total run time for dead threads */
HI(UInt, ThreadsTotalTime, 0L)
// Threads Array
HI(lockvar, ThreadHandlesLock, MkLock)
#endif
#if defined(YAPOR) || defined(THREADS)
// protect long critical regions
HI(lockvar, BGL, MkLock)
#endif
#if defined(YAPOR) || defined(TABLING)
HSPACE(struct global_optyap_data, optyap_data)
#endif /* YAPOR || TABLING */
// whether Yap is responsible for signal handling
HSPACE(int, PrologShouldHandleInterrupts)
/* This is the guy who actually started the system, and who has the correct
* registers */
#if defined(THREADS)
HSPACE(pthread_t, master_thread)
HI(struct thread_mbox *, named_mboxes, NULL)
HI(lockvar, mboxq_lock, MkLock)
HI(UInt, mbox_count, 0)
HSPACE(struct swi_mutex *, WithMutex)
#endif /* THREADS */
// streams
HSPACE(struct stream_desc *, Stream)
#if defined(THREADS) || defined(YAPOR)
HI(lockvar, StreamDescLock MkLock)
#endif
// access to yap initial arguments
HSPACE(char **, argv)
HSPACE(int, argc)
// extensions to Terms
#ifdef COROUTINING
/* array with the ops for your favourite extensions */
HSPACEN(ext_op, attvars_ext + 1, attas)
#endif
// agc.c
HSPACE(int, agc_calls)
HSPACE(YAP_ULONG_LONG, agc_collected)
/* total time spent in GC */
HI(Int, tot_agc_time, 0)
/* number of heap objects in all garbage collections */
HI(Int, tot_agc_recovered, 0)
// arrays.c
#if HAVE_MMAP
HI(struct MMAP_ARRAY_BLOCK *, mmap_arrays, NULL)
#endif
#ifdef DEBUG
// computils.c
HSPACEN(char, 20, Option)
HSPACE(YP_FILE *, logfile)
// init.c
// int , output_msg , false
#endif
#if defined(COFF) || defined(A_OUT)
// loada_coff.c && load_aout.c
HSPACEN(char, Executable, YAP_FILENAME_MAX)
#endif
HI(int, OpaqueHandlersCount, 0)
HI(struct opaque_handler_struct *, OpaqueHandlers, NULL)
#if __simplescalar__
HSPACEN(char, pwd, YAP_FILENAME_MAX)
#endif
// udi.c
// struct udi_control_block , RtreeCmd, void,
HSPACE(char *, RestoreFile)
// gprof.c
HSPACE(Int, ProfCalls)
HSPACE(Int, ProfGCs)
HSPACE(Int, ProfHGrows)
HSPACE(Int, ProfSGrows)
HSPACE(Int, ProfMallocs)
HSPACE(Int, ProfIndexing)
HSPACE(Int, ProfOn)
HSPACE(Int, ProfOns)
HSPACE(struct RB_red_blk_node *, ProfilerRoot)
HSPACE(struct RB_red_blk_node *, ProfilerNil)
HI(char *, DIRNAME, NULL)
#if LOW_PROF
HI(int, ProfilerOn, false)
HI(FILE *, FProf, NULL)
HI(FILE *, FPreds, NULL)
#endif /* LOW_PROF */
// Mutexes
#if THREADS
HI(struct swi_mutex *, FreeMutexes, NULL)
HI(struct swi_mutex *, mutex_backbone, NULL)
HSPACEN(struct swi_reverse_hash, N_SWI_HASH. SWI_ReverseHash
HI(lockvar, MUT_ACCESS, MkLock)
#endif
HI(char *, Home, NULL)
/* ISO char conversion: I will make no comments */
HI(char *, CharConversionTable, NULL)
HI(char *, CharConversionTable2, NULL)
/* time */
HI(void *, LastWTimePtr, NULL)
/* max priority */
HI(int, MaxPriority, 1200)

View File

@ -297,6 +297,7 @@ check_function_exists(mkstemp HAVE_MKSTEMP)
check_function_exists(mktemp HAVE_MKTEMP) check_function_exists(mktemp HAVE_MKTEMP)
check_function_exists(nanosleep HAVE_NANOSLEEP) check_function_exists(nanosleep HAVE_NANOSLEEP)
check_function_exists(mktime HAVE_MKTIME) check_function_exists(mktime HAVE_MKTIME)
check_function_exists(mtrace HAVE_MTRACE)
check_function_exists(opendir HAVE_OPENDIR) check_function_exists(opendir HAVE_OPENDIR)
if (NOT APPLE) if (NOT APPLE)
check_function_exists(open_memstream HAVE_OPEN_MEMSTREAM) check_function_exists(open_memstream HAVE_OPEN_MEMSTREAM)

View File

@ -31,6 +31,7 @@ set (ENGINE_SOURCES
C/corout.c C/corout.c
C/cut_c.c C/cut_c.c
C/dbase.c C/dbase.c
C/dbload.c
C/dlmalloc.c C/dlmalloc.c
C/errors.c C/errors.c
C/eval.c C/eval.c

View File

@ -942,6 +942,11 @@ function. */
#cmakedefine HAVE_MPI_H ${HAVE_MPI_H} #cmakedefine HAVE_MPI_H ${HAVE_MPI_H}
#endif #endif
/* Define to 1 if you have the <mtrace> glibc extension. */
#ifndef HAVE_MPI_H
#cmakedefine HAVE_MTRACE ${HAVE_TRACE}
#endif
/* Older versions of MPZ didn't have XOR */ /* Older versions of MPZ didn't have XOR */
#ifndef HAVE_MPZ_XOR #ifndef HAVE_MPZ_XOR
#cmakedefine HAVE_MPZ_XOR ${HAVE_MPZ_XOR} #cmakedefine HAVE_MPZ_XOR ${HAVE_MPZ_XOR}

View File

@ -137,13 +137,14 @@ typedef enum {
#include "YapInit.h" #include "YapInit.h"
/* this should be opaque to the user */ /* this should be opaque to the user */
typedef struct goal_info { typedef struct {
unsigned long b_top, b_bottom, m, e, y; //> choice-point at entry unsigned long b0, b_entry, b_exit; //> choice-point at entry
YAP_handle_t CurSlot; //> variables at entry YAP_handle_t CurSlot; //> variables at entry
YAP_handle_t EndSlot; //> variables at successful execution YAP_handle_t EndSlot; //> variables at successful execution
struct yami *p; //> Program Counter at entry struct yami *p; //> Program Counter at entry
struct yami *cp; //> Continuation PC at entry struct yami *cp; //> Continuation PC at entry
int lvl; int lvl;
long env0;
unsigned long tr, h; unsigned long tr, h;
} YAP_dogoalinfo; } YAP_dogoalinfo;

View File

@ -73,7 +73,8 @@ Yap_Error__(false, __FILE__, __FUNCTION__, __LINE__, id, TermNil, __VA_ARGS__)
{ if ( (TF = Yap_ensure_atom__(__FILE__, __FUNCTION__, __LINE__, T0 ) == 0L ) return false; \ { if ( (TF = Yap_ensure_atom__(__FILE__, __FUNCTION__, __LINE__, T0 ) == 0L ) return false; \
} }
INLINE_ONLY Term Yap_ensure_atom__(const char *fu, const char *fi, int line, //INLINE_ONLY
static Term Yap_ensure_atom__(const char *fu, const char *fi, int line,
Term in) { Term in) {
Term t = Deref(in); Term t = Deref(in);
// Term Context = Deref(ARG2); // Term Context = Deref(ARG2);

View File

@ -13,11 +13,11 @@ mkdir $PREFIX/conda
cd $PREFIX/conda cd $PREFIX/conda
# The datarootdir option places the docs into a temp folder that won't # The datarootdir option places the docs into a temp folder that won't
$CMAKE --build=. --target=install \ $CMAKE --build=. --target=install \
-DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_BUILD_TYPE=Debug -GNinja \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \ -DCMAKE_INSTALL_PREFIX="$PREFIX" \
$RECIPE_DIR/.. $RECIPE_DIR/.. -DWITH_CUDD=NO -DWITH_GECODE=NO -DWITH_JAVA=NO -DWITH_RAPTOR=NO
make -j install ninja install
# Remove the created lib64 directory # Remove the created lib64 directory

View File

@ -15,7 +15,6 @@ requirements:
- r - r
- notebook - notebook
- pkgconfig - pkgconfig
- make
- libxml2 - libxml2
run: run:
- jupyterlab - jupyterlab

View File

@ -710,7 +710,7 @@ scanl_([H1|T1], [H2|T2], [H3|T3], [H4|T4], Goal, V, [VH|VT]) :-
goal_expansion(checklist(Meta, List), Mod:Goal) :- goal_expansion(checklist(Meta, List), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -731,7 +731,7 @@ goal_expansion(checklist(Meta, List), Mod:Goal) :-
goal_expansion(maplist(Meta, List), Mod:Goal) :- goal_expansion(maplist(Meta, List), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -752,7 +752,7 @@ goal_expansion(maplist(Meta, List), Mod:Goal) :-
goal_expansion(maplist(Meta, ListIn, ListOut), Mod:Goal) :- goal_expansion(maplist(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -773,7 +773,7 @@ goal_expansion(maplist(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion(maplist(Meta, L1, L2, L3), Mod:Goal) :- goal_expansion(maplist(Meta, L1, L2, L3), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -794,7 +794,7 @@ goal_expansion(maplist(Meta, L1, L2, L3), Mod:Goal) :-
goal_expansion(maplist(Meta, L1, L2, L3, L4), Mod:Goal) :- goal_expansion(maplist(Meta, L1, L2, L3, L4), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -815,7 +815,7 @@ goal_expansion(maplist(Meta, L1, L2, L3, L4), Mod:Goal) :-
goal_expansion(maplist(Meta, L1, L2, L3, L4, L5), Mod:Goal) :- goal_expansion(maplist(Meta, L1, L2, L3, L4, L5), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -836,7 +836,7 @@ goal_expansion(maplist(Meta, L1, L2, L3, L4, L5), Mod:Goal) :-
goal_expansion(selectlist(Meta, ListIn, ListOut), Mod:Goal) :- goal_expansion(selectlist(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -859,7 +859,7 @@ goal_expansion(selectlist(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion(selectlist(Meta, ListIn, ListIn1, ListOut), Mod:Goal) :- goal_expansion(selectlist(Meta, ListIn, ListIn1, ListOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -882,7 +882,7 @@ goal_expansion(selectlist(Meta, ListIn, ListIn1, ListOut), Mod:Goal) :-
goal_expansion(selectlists(Meta, ListIn, ListIn1, ListOut, ListOut1), Mod:Goal) :- goal_expansion(selectlists(Meta, ListIn, ListIn1, ListOut, ListOut1), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -906,7 +906,7 @@ goal_expansion(selectlists(Meta, ListIn, ListIn1, ListOut, ListOut1), Mod:Goal)
% same as selectlist % same as selectlist
goal_expansion(include(Meta, ListIn, ListOut), Mod:Goal) :- goal_expansion(include(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -929,7 +929,7 @@ goal_expansion(include(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion(exclude(Meta, ListIn, ListOut), Mod:Goal) :- goal_expansion(exclude(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -952,7 +952,7 @@ goal_expansion(exclude(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion(partition(Meta, ListIn, List1, List2), Mod:Goal) :- goal_expansion(partition(Meta, ListIn, List1, List2), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -975,7 +975,7 @@ goal_expansion(partition(Meta, ListIn, List1, List2), Mod:Goal) :-
goal_expansion(partition(Meta, ListIn, List1, List2, List3), Mod:Goal) :- goal_expansion(partition(Meta, ListIn, List1, List2, List3), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1015,7 +1015,7 @@ goal_expansion(partition(Meta, ListIn, List1, List2, List3), Mod:Goal) :-
goal_expansion(convlist(Meta, ListIn, ListOut), Mod:Goal) :- goal_expansion(convlist(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1038,7 +1038,7 @@ goal_expansion(convlist(Meta, ListIn, ListOut), Mod:Goal) :-
goal_expansion(convlist(Meta, ListIn, ListExtra, ListOut), Mod:Goal) :- goal_expansion(convlist(Meta, ListIn, ListExtra, ListOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1061,7 +1061,7 @@ goal_expansion(convlist(Meta, ListIn, ListExtra, ListOut), Mod:Goal) :-
goal_expansion(sumlist(Meta, List, AccIn, AccOut), Mod:Goal) :- goal_expansion(sumlist(Meta, List, AccIn, AccOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1082,7 +1082,7 @@ goal_expansion(sumlist(Meta, List, AccIn, AccOut), Mod:Goal) :-
goal_expansion(foldl(Meta, List, AccIn, AccOut), Mod:Goal) :- goal_expansion(foldl(Meta, List, AccIn, AccOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1103,7 +1103,7 @@ goal_expansion(foldl(Meta, List, AccIn, AccOut), Mod:Goal) :-
goal_expansion(foldl(Meta, List1, List2, AccIn, AccOut), Mod:Goal) :- goal_expansion(foldl(Meta, List1, List2, AccIn, AccOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1124,7 +1124,7 @@ goal_expansion(foldl(Meta, List1, List2, AccIn, AccOut), Mod:Goal) :-
goal_expansion(foldl(Meta, List1, List2, List3, AccIn, AccOut), Mod:Goal) :- goal_expansion(foldl(Meta, List1, List2, List3, AccIn, AccOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1145,7 +1145,7 @@ goal_expansion(foldl(Meta, List1, List2, List3, AccIn, AccOut), Mod:Goal) :-
goal_expansion(foldl2(Meta, List, AccIn, AccOut, W0, W), Mod:Goal) :- goal_expansion(foldl2(Meta, List, AccIn, AccOut, W0, W), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1166,7 +1166,7 @@ goal_expansion(foldl2(Meta, List, AccIn, AccOut, W0, W), Mod:Goal) :-
goal_expansion(foldl2(Meta, List1, List2, AccIn, AccOut, W0, W), Mod:Goal) :- goal_expansion(foldl2(Meta, List1, List2, AccIn, AccOut, W0, W), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1187,7 +1187,7 @@ goal_expansion(foldl2(Meta, List1, List2, AccIn, AccOut, W0, W), Mod:Goal) :-
goal_expansion(foldl2(Meta, List1, List2, List3, AccIn, AccOut, W0, W), Mod:Goal) :- goal_expansion(foldl2(Meta, List1, List2, List3, AccIn, AccOut, W0, W), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1208,7 +1208,7 @@ goal_expansion(foldl2(Meta, List1, List2, List3, AccIn, AccOut, W0, W), Mod:Goal
goal_expansion(foldl3(Meta, List, AccIn, AccOut, W0, W, X0, X), Mod:Goal) :- goal_expansion(foldl3(Meta, List, AccIn, AccOut, W0, W, X0, X), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1229,7 +1229,7 @@ goal_expansion(foldl3(Meta, List, AccIn, AccOut, W0, W, X0, X), Mod:Goal) :-
goal_expansion(foldl4(Meta, List, AccIn, AccOut, W0, W, X0, X, Y0, Y), Mod:Goal) :- goal_expansion(foldl4(Meta, List, AccIn, AccOut, W0, W, X0, X, Y0, Y), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1250,7 +1250,7 @@ goal_expansion(foldl4(Meta, List, AccIn, AccOut, W0, W, X0, X, Y0, Y), Mod:Goal)
goal_expansion(mapnodes(Meta, InTerm, OutTerm), Mod:Goal) :- goal_expansion(mapnodes(Meta, InTerm, OutTerm), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1282,7 +1282,7 @@ goal_expansion(mapnodes(Meta, InTerm, OutTerm), Mod:Goal) :-
goal_expansion(checknodes(Meta, Term), Mod:Goal) :- goal_expansion(checknodes(Meta, Term), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,
@ -1312,7 +1312,7 @@ goal_expansion(checknodes(Meta, Term), Mod:Goal) :-
goal_expansion(sumnodes(Meta, Term, AccIn, AccOut), Mod:Goal) :- goal_expansion(sumnodes(Meta, Term, AccIn, AccOut), Mod:Goal) :-
goal_expansion_allowed, goal_expansion_allowed,
is_callable(Meta), callable(Meta),
current_source_module(Mod,Mod), current_source_module(Mod,Mod),
aux_preds(Meta, MetaVars, Pred, PredVars, Proto), aux_preds(Meta, MetaVars, Pred, PredVars, Proto),
!, !,

View File

@ -1934,6 +1934,19 @@ static Int p_sleep(USES_REGS1) {
#endif #endif
} }
static Int
p_mtrace()
{
#ifdef HAVE_MTRACE
Term t = Deref(ARG1);
if (t == TermTrue) mtrace();
else if (t == TermFalse) return muntrace();
else return false;
#endif
return true;
}
void Yap_InitSysPreds(void) { void Yap_InitSysPreds(void) {
Yap_InitCPred("log_event", 1, p_log_event, SafePredFlag | SyncPredFlag); Yap_InitCPred("log_event", 1, p_log_event, SafePredFlag | SyncPredFlag);
Yap_InitCPred("sh", 0, p_sh, SafePredFlag | SyncPredFlag); Yap_InitCPred("sh", 0, p_sh, SafePredFlag | SyncPredFlag);
@ -1972,5 +1985,6 @@ void Yap_InitSysPreds(void) {
Yap_InitCPred("rmdir", 2, p_rmdir, SyncPredFlag); Yap_InitCPred("rmdir", 2, p_rmdir, SyncPredFlag);
Yap_InitCPred("sleep", 1, p_sleep, SyncPredFlag); Yap_InitCPred("sleep", 1, p_sleep, SyncPredFlag);
Yap_InitCPred("make_directory", 1, make_directory, SyncPredFlag); Yap_InitCPred("make_directory", 1, make_directory, SyncPredFlag);
Yap_InitCPred("mtrace", 1, p_mtrace, SyncPredFlag);
} }

View File

@ -729,6 +729,7 @@ char *Yap_TermToBuffer(Term t, int flags) {
t = Deref(t); t = Deref(t);
GLOBAL_Stream[sno].encoding = LOCAL_encoding; GLOBAL_Stream[sno].encoding = LOCAL_encoding;
GLOBAL_Stream[sno].status |= CloseOnException_Stream_f; GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
GLOBAL_Stream[sno].status &= ~FreeOnClose_Stream_f;
Yap_plwrite(t, GLOBAL_Stream + sno, 0, flags, GLOBAL_MaxPriority); Yap_plwrite(t, GLOBAL_Stream + sno, 0, flags, GLOBAL_MaxPriority);
char *new = Yap_MemExportStreamPtr(sno); char *new = Yap_MemExportStreamPtr(sno);

105
packages/bee/CMakeLists.txt Normal file
View File

@ -0,0 +1,105 @@
set (MINISAT_SOURCES
#minisat-2.0.2/core/Main.cc
minisat-2.0.2/core/Solver.cc
#minisat-2.0.2/simp/Main.cc
minisat-2.0.2/simp/SimpSolver.cc
minisat-2.0.2/utils/Options.cc
minisat-2.0.2/utils/System.cc
)
add_library( MINISAT
${MINISAT_SOURCES}
minisat-interface.cc
)
target_link_libraries (MINISAT libYap)
set_target_properties(MINISAT PROPERTIES CXX_STANDARD 11)
target_include_directories(MINISAT PRIVATE BEFORE minisat-2.0.2/core)
target_include_directories(MINISAT PRIVATE BEFORE minisat-2.0.2)
set_target_properties(MINISAT PROPERTIES COMPILE_FLAGS -DMINISAT=1)
set_target_properties(MINISAT PROPERTIES CXX_STANDARD 11)
set(solver minisat)
set (Solver Minisat)
configure_file(yap-interface.cc.cmake minisat-interface.cc)
if(OFF)
set(
CRYPTOMINISAT_SOURCES
cryptominisat-2.5.1/Solver/Clause.cpp
cryptominisat-2.5.1/Solver/ClauseCleaner.cpp
cryptominisat-2.5.1/Solver/FailedVarSearcher.cpp
cryptominisat-2.5.1/Solver/FindUndef.cpp
cryptominisat-2.5.1/Solver/Gaussian.cpp
cryptominisat-2.5.1/Solver/Logger.cpp
cryptominisat-2.5.1/Solver/MatrixFinder.cpp
cryptominisat-2.5.1/Solver/PackedRow.cpp
cryptominisat-2.5.1/Solver/PartFinder.cpp
cryptominisat-2.5.1/Solver/PartHandler.cpp
cryptominisat-2.5.1/Solver/RestartTypeChooser.cpp
cryptominisat-2.5.1/Solver/SmallPtr.cpp
cryptominisat-2.5.1/Solver/Solver.cpp
cryptominisat-2.5.1/Solver/StateSaver.cpp
cryptominisat-2.5.1/Solver/Subsumer.cpp
cryptominisat-2.5.1/Solver/VarReplacer.cpp
cryptominisat-2.5.1/Solver/XorFinder.cpp
cryptominisat-2.5.1/Solver/XorSubsumer.cpp
)
add_library( CRYPTOMINISAT
${CRYPTOMINISAT_SOURCES}
cryptominisat-interface.cc
)
target_link_libraries (CRYPTOMINISAT libYap)
# target_include_directories(GLUCOSE4 PRIVATE glucose-4/parallel)
target_include_directories(CRYPTOMINISAT PRIVATE BEFORE cryptominisat-2.5.1/MTRand)
target_include_directories(CRYPTOMINISAT PRIVATE BEFORE cryptominisat-2.5.1/mtl)
target_include_directories(CRYPTOMINISAT PRIVATE BEFORE cryptominisat-2.5.1/Solver)
target_compile_definitions(CRYPTOMINISAT PUBLIC CRYPTOMINISAT=1 register=)
# set_target_properties(CRYPTOMINISAT PROPERTIES CXX_STANDARD 11)
set(solver cryptominisat)
set (Solver Cryptominisat)
configure_file(yap-interface.cc.cmake cryptominisat-interface.cc)
endif()
set(
GLUCOSE_SOURCES
# glucose-2.2/core/Main.cc
glucose-2.2/core/Solver.cc
# glucose-2.2/simp/Main.cc
glucose-2.2/simp/SimpSolver.cc
glucose-2.2/utils/Options.cc
glucose-2.2/utils/System.cc
)
add_library( GLUCOSE
${GLUCOSE_SOURCES}
glucose-interface.cc
)
target_link_libraries (GLUCOSE libYap)
set_target_properties(GLUCOSE PROPERTIES COMPILE_FLAGS -DGLUCOSE=1)
#set_target_properties(GLUCOSE PROPERTIES CXX_STANDARD 11)
target_include_directories(GLUCOSE PRIVATE glucose-2.2)
target_include_directories(GLUCOSE PRIVATE glucose-2.2/core)
set_target_properties(GLUCOSE PROPERTIES CXX_STANDARD 11)
set(solver glucose)
set (Solver Glucose)
configure_file(yap-interface.cc.cmake glucose-interface.cc)
# add_library( GLUCOSE4
# ${GLUCOSE4_SOURCES}
# ${PL_SOURCE}
# )
# set_target_properties(GLUCOSE4 PROPERTIES COMPILE_FLAGS -DGLUCOSE4=1)
# set_target_properties(GLUCOSE4 PROPERTIES CXX_STANDARD 11)
# target_include_directories(GLUCOSE4 PRIVATE glucose-4/parallel)
# target_include_directories(GLUCOSE4 PRIVATE glucose-4)

25
packages/bee/cryptominisat-2.5.1/AUTHORS vendored Executable file
View File

@ -0,0 +1,25 @@
Mate Soos <soos.mate@gmail.com>
People whose code has been incorporated:
- Niklas Eén
- Niklas Sörensson
- Gilles Audemard
- Laurent Simon
- Some of Armin Biere's code
->> Great thanks to all of the above. They were not
in any way associated with the development of CryptoMiniSat.
Please don't blame them or write to them regarding bugs etc.
Special thanks to:
- the author's professors
- the gcc compiler team
- libstdc team
- Bjarne Stroustrup for C++
Bug-hunting thanks to:
- Martin Maurer for helping with Visual C-specific things
and reporting on multiple bugs
- Trevor Hansen, for fuzztesting the code on millions of problems
and reporting on a good number of bugs
- Vijay Ganesh for finding a lots of bugs
- Users of STP (Simple Theorem Prover) for their feedback

View File

@ -0,0 +1,48 @@
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
IF(DEFINED CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
ELSE()
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
ENDIF()
#set(CMAKE_C_COMPILER "gcc-4.4")
#set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.4")
PROJECT(cryptoms)
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-m32 -O3 -Wall -Werror -DSTATS_NEEDED -g -mtune=native")
SET(CMAKE_CXX_FLAGS_DEBUG "-Wall -Wextra -Werror -DSTATS_NEEDED -O0 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "-Wall -fprofile-use -Werror -O3 -g0 -fno-exceptions -DNDEBUG -mtune=native -fomit-frame-pointer")
SET(CMAKE_EXE_LINKER_FLAGS "-static")
find_package( ZLIB )
link_directories( ${ZLIB_LIBRARY} )
include_directories( ${ZLIB_INCLUDE_DIR} )
find_package(Boost)
if(Boost_FOUND)
message("Boost found --- clauses will be packed (speedup)")
add_definitions(-DUSE_POOLS)
else(Boost_FOUND)
message("Boost NOT found, so clauses will NOT be packed (slowdown)")
endif(Boost_FOUND)
add_definitions(-DVERSION="2.5.1")
#FIND_PACKAGE(Threads REQUIRED)
#set(thread_library "${CMAKE_THREAD_LIBS_INIT}")
add_subdirectory(Solver)
#add_subdirectory(SatELite)
add_custom_target(copy ALL
COMMENT "Copying binaries from subdirs to build directory")
add_custom_command(
TARGET copy
COMMAND ${CMAKE_COMMAND} -E copy Solver/cryptominisat .
# COMMAND ${CMAKE_COMMAND} -E copy SatELite/satelite .
)
#add_dependencies(copy cryptominisat satelite)
add_dependencies(copy cryptominisat)

View File

@ -0,0 +1,82 @@
*****************************
general info
*****************************
mingw32-w32 is in Debian
http://man.gnusquad.org/i586-mingw32msvc-ar/section-1/en/
64-bit mingw32 build instructions:
http://www.cadforte.com/wiki/index.php/How_to_build
building libraries:
http://wiki.njh.eu/Cross_Compiling_for_Win32
http://stackoverflow.com/questions/1399252/boost-cross-compile-from-linux-to-windows
in my user-config.jam: "using gcc : m : i586-mingw32msvc-g++ ;". I then run: "bjam toolset=gcc-m target-os=windows variant=debug --with-program_options".
So the whole command is: "./bjam --layout=system variant=release threading=multi link=shared runtime-link=shared toolset=gcc target-os=windows threadapi=win32 stage". cannot compile these libraries: -graph -graph_parallel -iostreams -math (partly) -python The others can be compiled.
use --without-xxx to disable building unneeded libraries
boost build:
./bootstrap
./bjam --layout=system variant=release threading=multi link=shared runtime-link=shared toolset=gcc target-os=windows threadapi=win32 --without-graph --without-graph_parallel --without-iostreams --without-math --without-python stage
*****************************
how to compile stuff on debian mingw32-w32
*****************************
make line:
PATH=/usr/i586-mingw32msvc/bin:$PATH \
make CC=i586-mingw32msvc-gcc AR=i586-mingw32msvc-ar \
RC=i586-mingw32msvc-windres
for libz, the last line is:
i586-mingw32msvc-ar qs libz.a adler32.o \
compress.o crc32.o gzio.o uncompr.o \
deflate.o trees.o zutil.o inflate.o \
infback.o inftrees.o inffast.o
make install PREFIX=/usr/i586-mingw32msvc
*****************************
how to compile stuff on debian mingw32-w64
*****************************
make line:
PATH=/usr/x86_64-w64-mingw32/bin:$PATH \
make CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar \
RC=x86_64-w64-mingw32-windres
for libz, the last line is:
x86_64-w64-mingw32-ar qs libz.a adler32.o \
compress.o crc32.o gzio.o uncompr.o \
deflate.o trees.o zutil.o inflate.o \
infback.o inftrees.o inffast.o
*****************************
compile minisat
*****************************
i586-mingw32msvc-g++ -O3 -march=i586 -DVERSION=\"2.5.1\" -DCROSS_COMPILE \
-I../mtl/ -I../MTRand/ Main.C /usr/i586-mingw32msvc/lib/libz.a \
Logger.cpp Solver.cpp ClauseCleaner.cpp FindUndef.cpp \
PackedRow.cpp RestartTypeChooser.cpp MatrixFinder.cpp Gaussian.cpp \
VarReplacer.cpp XorFinder.cpp SmallPtr.cpp Clause.cpp PartHandler.cpp \
Subsumer.cpp XorSubsumer.cpp FailedVarSearcher.cpp PartFinder.cpp \
StateSaver.cpp -o cryptominisat.exe
*****************************
useful for examining archives:
*****************************
i586-mingw32msvc-nm libz.a
i586-mingw32msvc-objdump -G libz.a
*****************************
Useful
*****************************
./configure --host=x86_64-pc-linux --target=x86_64-pc-mingw32

View File

@ -0,0 +1,21 @@
If compiling with Visual C, the CHUNK_LIMIT poses problems.
Problem is, that VC2008 seems to have a too small default stack, which is not big enough.
With default command line parameters it will crash.
The workaround is to give the command line parameter /F. With this you can
increase the stack to a certain size. Setting it to 2 MB is good enough
ZLIB might also pose problems. If you cannot correctly compile it under
windows, I suggest you add the -DDISABLE_ZLIB to your compilation flags.
The compilation instruction should therefore be:
cl /favor:INTEL64 /O2 /Fecryptominisat.exe -DDISABLE_ZLIB /F2097152
/TP /EHsc -I. -I../mtl/ -I../MTRand/ Main.C Logger.cpp Solver.cpp
ClauseCleaner.cpp Conglomerate.cpp FindUndef.cpp
PackedRow.cpp RestartTypeChooser.cpp VarReplacer.cpp
XorFinder.cpp XorSubsumer.cpp Subsumer.cpp PartFinder.cpp
PartHandler.cpp FailedVarSearcher.cpp Gaussian.cpp
MatrixFinder.cpp
executed from the 'Solver' subdirectory
--- Bulid instructions by Martin M., thanks for all Visual C-based testing

88
packages/bee/cryptominisat-2.5.1/INSTALL vendored Executable file
View File

@ -0,0 +1,88 @@
-----------
Libraries needed
-----------
You will need the following libraries to compile the sources:
* libz
-----------------
Building the source
-----------------
There are two ways to build the source. With cmake or with autotools.
I personally use cmake.
-----------------
Building using cmake
-----------------
* Install cmake
* Go into the 'build' directory
* Issue 'cmake ../'
* Issue 'make'
* Issue './cryptominisat satfile.cnf'
to test your new code.
------------------
Building using autotools
------------------
* Go to the 'build' directory
* Issue '../configure'
* Issue 'make'
* Issue './cryptominisat satfile.cnf' to test your new code
If you got your source from the GIT/SVN, then you should do the following
before doing the above::
* Install automake, autoconf, libtool
* Issue 'make -f Makefile.cvs' in the root dir of the source
---------
Please read help
---------
For help, build the program, and issue:
'./cryptominisat -help'
--------------
Verbose debug
-------------
You can also turn on verbose debugging.
Simply remove the comment before
"//#define VERBOSE_DEBUG"
in Solver/constants.h and re-compile
When executing:
'./cryptominisat satfile.cnf'
You will see a LOT of debug info. You should therefore maybe do:
'./cryptominisat satfile.cnf > debuginfo.txt'
then you can open the 'debuginfo.txt' file from a text editor and have a look
--------------------------
Windows binary generation
-------------------------
It should be possible f you compile under windows
using Visual C++. Please read the HOWTO_VisualCpp for details
I compile under linux all windows binaries, using gcc that generates
windows executables. It works really well. There is a sort-of-howto in
the "HOWTO_MinGW32" text file. A short step-by-step is here:
1) Install gcc that generates windows binaries:
i586-mingw32msvc
1) Install all libraries (libz)
libz:
get from source and compile as per "Solver/win32-howto"
2) complie:
go to the "Solver" subdir and execute:
i586-mingw32msvc-g++ -O3 -g -DCROSS_COMPILE -march=i586 -I../mtl/ -I../MTRand/ \
/usr/i586-mingw32msvc/lib/libz.a Main.C Solver.C Logger.C Clause.cpp \
VarReplacer.cpp FindUndef.cpp XorFinder.cpp XorSubsumer.cpp Subsumer.cpp \
Conglomerate.cpp PackedRow.cpp FailedVarSearcher.cpp PartFinder.cpp \
PartHander.cpp -o cryptominisat.exe
I test the generated binary under wine, in Linux.

674
packages/bee/cryptominisat-2.5.1/LICENSE-GPL vendored Executable file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

21
packages/bee/cryptominisat-2.5.1/LICENSE-MIT vendored Executable file
View File

@ -0,0 +1,21 @@
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,423 @@
// MersenneTwister.h
// Mersenne Twister random number generator -- a C++ class MTRand
// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com
// The Mersenne Twister is an algorithm for generating random numbers. It
// was designed with consideration of the flaws in various other generators.
// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
// are far greater. The generator is also fast; it avoids multiplication and
// division, and it benefits from caches and pipelines. For more information
// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
// Reference
// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
// Copyright (C) 2000 - 2003, Richard J. Wagner
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The names of its contributors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The original code included the following notice:
//
// When you use this, send an email to: matumoto@math.keio.ac.jp
// with an appropriate reference to your work.
//
// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu
// when you write.
#ifndef MERSENNETWISTER_H
#define MERSENNETWISTER_H
// Not thread safe (unless auto-initialization is avoided and each thread has
// its own MTRand object)
#include <iostream>
#include <limits.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
class MTRand {
// Data
public:
typedef unsigned long uint32; // unsigned integer type, at least 32 bits
enum { N = 624 }; // length of state vector
enum { SAVE = N + 1 }; // length of array for save()
protected:
enum { M = 397 }; // period parameter
uint32 state[N]; // internal state
uint32 *pNext; // next value to get from state
int left; // number of values left before reload needed
//Methods
public:
MTRand( const uint32& oneSeed ); // initialize with a simple uint32
MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
MTRand(); // auto-initialize with /dev/urandom or time() and clock()
// Do NOT use for CRYPTOGRAPHY without securely hashing several returned
// values together, otherwise the generator state can be learned after
// reading 624 consecutive values.
// Access to 32-bit random numbers
double rand(); // real number in [0,1]
double rand( const double& n ); // real number in [0,n]
double randExc(); // real number in [0,1)
double randExc( const double& n ); // real number in [0,n)
double randDblExc(); // real number in (0,1)
double randDblExc( const double& n ); // real number in (0,n)
uint32 randInt(); // integer in [0,2^32-1]
uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
double operator()() { return rand(); } // same as rand()
// Access to 53-bit random numbers (capacity of IEEE double precision)
double rand53(); // real number in [0,1)
// Access to nonuniform random number distributions
double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
// Re-seeding functions with same behavior as initializers
void seed( const uint32 oneSeed );
void seed( uint32 *const bigSeed, const uint32 seedLength = N );
void seed();
// Saving and loading generator state
void save( uint32* saveArray ) const; // to array of size SAVE
void load( uint32 *const loadArray ); // from such array
friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
protected:
void initialize( const uint32 oneSeed );
void reload();
uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
uint32 mixBits( const uint32& u, const uint32& v ) const
{ return hiBit(u) | loBits(v); }
uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
static uint32 hash( time_t t, clock_t c );
};
inline MTRand::MTRand( const uint32& oneSeed )
{ seed(oneSeed); }
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
{ seed(bigSeed,seedLength); }
inline MTRand::MTRand()
{ seed(); }
inline double MTRand::rand()
{ return double(randInt()) * (1.0/4294967295.0); }
inline double MTRand::rand( const double& n )
{ return rand() * n; }
inline double MTRand::randExc()
{ return double(randInt()) * (1.0/4294967296.0); }
inline double MTRand::randExc( const double& n )
{ return randExc() * n; }
inline double MTRand::randDblExc()
{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
inline double MTRand::randDblExc( const double& n )
{ return randDblExc() * n; }
inline double MTRand::rand53()
{
uint32 a = randInt() >> 5, b = randInt() >> 6;
return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
}
inline double MTRand::randNorm( const double& mean, const double& variance )
{
// Return a real number from a normal (Gaussian) distribution with given
// mean and variance by Box-Muller method
double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
return mean + r * cos(phi);
}
inline MTRand::uint32 MTRand::randInt()
{
// Pull a 32-bit integer from the generator state
// Every other access function simply transforms the numbers extracted here
if( left == 0 ) reload();
--left;
register uint32 s1;
s1 = *pNext++;
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9d2c5680UL;
s1 ^= (s1 << 15) & 0xefc60000UL;
return ( s1 ^ (s1 >> 18) );
}
inline MTRand::uint32 MTRand::randInt( const uint32& n )
{
// Find which bits are used in n
// Optimized by Magnus Jonsson (magnus@smartelectronix.com)
uint32 used = n;
used |= used >> 1;
used |= used >> 2;
used |= used >> 4;
used |= used >> 8;
used |= used >> 16;
// Draw numbers until one is found in [0,n]
uint32 i;
do
i = randInt() & used; // toss unused bits to shorten search
while( i > n );
return i;
}
inline void MTRand::seed( const uint32 oneSeed )
{
// Seed the generator with a simple uint32
initialize(oneSeed);
reload();
}
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
{
// Seed the generator with an array of uint32's
// There are 2^19937-1 possible initial states. This function allows
// all of those to be accessed by providing at least 19937 bits (with a
// default seed length of N = 624 uint32's). Any bits above the lower 32
// in each element are discarded.
// Just call seed() if you want to get array from /dev/urandom
initialize(19650218UL);
register int i = 1;
register uint32 j = 0;
register int k = ( N > seedLength ? N : seedLength );
for( ; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
state[i] &= 0xffffffffUL;
++i; ++j;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
if( j >= seedLength ) j = 0;
}
for( k = N - 1; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
state[i] -= i;
state[i] &= 0xffffffffUL;
++i;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
}
state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
reload();
}
inline void MTRand::seed()
{
// Seed the generator with an array from /dev/urandom if available
// Otherwise use a hash of time() and clock() values
// First try getting an array from /dev/urandom
FILE* urandom = fopen( "/dev/urandom", "rb" );
if( urandom )
{
uint32 bigSeed[N];
register uint32 *s = bigSeed;
register int i = N;
register bool success = true;
while( success && i-- )
success = fread( s++, sizeof(uint32), 1, urandom );
fclose(urandom);
if( success ) { seed( bigSeed, N ); return; }
}
// Was not successful, so use time() and clock() instead
seed( hash( time(NULL), clock() ) );
}
inline void MTRand::initialize( const uint32 seed )
{
// Initialize generator state with seed
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
// In previous versions, most significant bits (MSBs) of the seed affect
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
register uint32 *s = state;
register uint32 *r = state;
register int i = 1;
*s++ = seed & 0xffffffffUL;
for( ; i < N; ++i )
{
*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
r++;
}
}
inline void MTRand::reload()
{
// Generate N new values in state
// Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
register uint32 *p = state;
register int i;
for( i = N - M; i--; ++p )
*p = twist( p[M], p[0], p[1] );
for( i = M; --i; ++p )
*p = twist( p[M-N], p[0], p[1] );
*p = twist( p[M-N], p[0], state[0] );
left = N, pNext = state;
}
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
{
// Get a uint32 from t and c
// Better than uint32(x) in case x is floating point in [0,1]
// Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
static uint32 differ = 0; // guarantee time-based seeds will change
uint32 h1 = 0;
unsigned char *p = (unsigned char *) &t;
for( size_t i = 0; i < sizeof(t); ++i )
{
h1 *= UCHAR_MAX + 2U;
h1 += p[i];
}
uint32 h2 = 0;
p = (unsigned char *) &c;
for( size_t j = 0; j < sizeof(c); ++j )
{
h2 *= UCHAR_MAX + 2U;
h2 += p[j];
}
return ( h1 + differ++ ) ^ h2;
}
inline void MTRand::save( uint32* saveArray ) const
{
register uint32 *sa = saveArray;
register const uint32 *s = state;
register int i = N;
for( ; i--; *sa++ = *s++ ) {}
*sa = left;
}
inline void MTRand::load( uint32 *const loadArray )
{
register uint32 *s = state;
register uint32 *la = loadArray;
register int i = N;
for( ; i--; *s++ = *la++ ) {}
left = *la;
pNext = &state[N-left];
}
inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
{
register const MTRand::uint32 *s = mtrand.state;
register int i = mtrand.N;
for( ; i--; os << *s++ << "\t" ) {}
return os << mtrand.left;
}
inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
{
register MTRand::uint32 *s = mtrand.state;
register int i = mtrand.N;
for( ; i--; is >> *s++ ) {}
is >> mtrand.left;
mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
return is;
}
#endif // MERSENNETWISTER_H
// Change log:
//
// v0.1 - First release on 15 May 2000
// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// - Translated from C to C++
// - Made completely ANSI compliant
// - Designed convenient interface for initialization, seeding, and
// obtaining numbers in default or user-defined ranges
// - Added automatic seeding from /dev/urandom or time() and clock()
// - Provided functions for saving and loading generator state
//
// v0.2 - Fixed bug which reloaded generator one step too late
//
// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
//
// v0.4 - Removed trailing newline in saved generator format to be consistent
// with output format of built-in types
//
// v0.5 - Improved portability by replacing static const int's with enum's and
// clarifying return values in seed(); suggested by Eric Heimburg
// - Removed MAXINT constant; use 0xffffffffUL instead
//
// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
// - Changed integer [0,n] generator to give better uniformity
//
// v0.7 - Fixed operator precedence ambiguity in reload()
// - Added access for real numbers in (0,1) and (0,n)
//
// v0.8 - Included time.h header to properly support time_t and clock_t
//
// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
// - Allowed for seeding with arrays of any length
// - Added access for real numbers in [0,1) with 53-bit resolution
// - Added access for real numbers from normal (Gaussian) distributions
// - Increased overall speed by optimizing twist()
// - Doubled speed of integer [0,n] generation
// - Fixed out-of-range number generation on 64-bit machines
// - Improved portability by substituting literal constants for long enum's
// - Changed license from GNU LGPL to BSD

10
packages/bee/cryptominisat-2.5.1/Makefile.am vendored Executable file
View File

@ -0,0 +1,10 @@
# not a GNU package. You can remove this line, if
# have all needed files, that a GNU package needs
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = Solver
all-local: Solver
cp Solver/cryptominisat .

10
packages/bee/cryptominisat-2.5.1/Makefile.cvs vendored Executable file
View File

@ -0,0 +1,10 @@
default: all
all:
aclocal
autoheader
libtoolize --copy
automake --copy --add-missing
automake
autoconf

733
packages/bee/cryptominisat-2.5.1/Makefile.in vendored Executable file
View File

@ -0,0 +1,733 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure AUTHORS INSTALL NEWS TODO config.guess \
config.sub depcomp install-sh ltmain.sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4-extra/boost.m4 $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
distdir dist dist-all distcheck
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d "$(distdir)" \
|| { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr "$(distdir)"; }; }
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_ROOT = @BOOST_ROOT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
# not a GNU package. You can remove this line, if
# have all needed files, that a GNU package needs
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = Solver
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-lzma: distdir
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
$(am__remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@$(am__cd) '$(distuninstallcheck_dir)' \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h all-local
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr \
distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
ctags-recursive install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am all-local am--refresh check check-am clean \
clean-generic clean-libtool ctags ctags-recursive dist \
dist-all dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ \
dist-xz dist-zip distcheck distclean distclean-generic \
distclean-hdr distclean-libtool distclean-tags distcleancheck \
distdir distuninstallcheck dvi dvi-am html html-am info \
info-am install install-am install-data install-data-am \
install-dvi install-dvi-am install-exec install-exec-am \
install-html install-html-am install-info install-info-am \
install-man install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am
all-local: Solver
cp Solver/cryptominisat .
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

174
packages/bee/cryptominisat-2.5.1/NEWS vendored Executable file
View File

@ -0,0 +1,174 @@
ver 2.5.1 -- 8/06/2010 --- 'The Obvious Child'
* Printing updates: everyting is printed much more nicely now
* Approximated degrees of literals in binary graph are not reset between
calculations
ver 2.5.0 -- 7/06/2010 (SAT Race'10 version)
* A lot of performance bugs have been fixed. Activities of clauses were wrongly
updated with their abstract representation during subsumtion for example.
Also, we now use a well-tested set of magic constants instead of making
them up using intuition. Apparently, intuition in the field of SAT leads
to headaches and (in severe cases) to dementia.
* A lot of code has been added regarding binary clause graphs. It is now
regularly cleaned from useless binary clauses. Also, the useless binary
clauses are regularly generated to subsume and strenghthen other clauses
with them -- and once used, these useless binary clauses are thrown away.
* Hyper-binary clauses are now generated using an algorithm relying purely
on the datastrucures available in modern SAT solvers -- i.e. the fact that
binary clauses have their own watchlists, and so allow for efficient
propagation of the binary clauses separately from other clauses.
ver 2.4.2 -- 9/05/2010
* Gaussian elimination has finally been fixed. It can now be tried out with
the command-line switch "--gaussuntil=X", where X is the maximum depth. I
usually set 100, but this is probably a wrong default. You should experiment
with your own cipher. NOTE: Gauss is still experimental. If it segfaults,
please file a bug.
* The solver can now print out all the solutions to a problem. Simply use the
"--maxsolutions=X" option, where X is the maximum number of solutions you
need. You may use this option in conjunction with the very experimental
"--greedyunbound" which unassigns some variables in such a way that the
given solution is still correct, but some variables may not appear in it.
* Command line switches have been corrected. They are now all lower-case and
use the prefix "--" instead of "-"
ver 2.4.1 -- 30/04/2010
Serious bug fixed that read data from change memory in subsume0, and
hyper-binary resolution has been disabled, since it caused satisfiable
instances to become unsatisfiable.
ver 2.4.0 -- 26/04/2010
The first real release of CryptoMiniSat v2. It contains the following set
of improvements:
* XOR clauses are extracted at the beginning of the solving
* Anti- or equivalent variables are detected at regular intervals
and are replaced with one another, eliminating variables during
solving
* xor-clauses are regularly XOR-ed with one another such as to obtain
binary XOR clauses. These binary xor-clauses are then treated as variable
replacements instructions (i.e. "v1 XOR v2 = false" means that v1 is
replaced with v2)
* Phase calculation using Jeroslow and Wang, and phase saving with
randomised search space exploration. The average branch depth is
measured for each instance, and the solver makes a random phase
flip with 1/avgBranchDepth probability
* Random search burst are used to search unexplored areas of the
search space at regular intervals
* Automatic detection of cryptographic and industrial instances. Dynamic
restart is used for industrial instances, and static restart for
cryptographical instances. Detection is based on xor-clause percentage
and variable activity stability.
* Regular full restarts are performed to detect if the problem hasn't
changed enough due to learnt clauses and assigned variables to behave
more like a cryptographical instance than an industrial instance or
vice-versa.
* Both GLUCOSE-type learnt clause activity and MiniSat-type learnt clause
activity heuristics are supported. During dynamic restarts, the GLUCOSE
heuristic is used, while during static restarts, the MiniSat-type
heuristic is used.
* SatELite-type variable elimination, clause subsumption and clause
strengthening is regularly performed. The occurrence lists are, however,
not updated all the time such as the case is with PrecoSat. Instead,
occurrences are calculated on per-use basis
* On-the-fly subsumption is used to check whether the conflict clause
automatically subsumes the clause that caused the conflict.
* Binary clauses are propagated first before non-binary clauses are
propagated.
* 32-bit pointers are used for the watchlists on 64-bit architectures,
using out the fact that most bits in the 64-bit pointer are actually fixed
* Hyper-binary resolution is used when the hyper-binary clause subsumes
any of the original clauses
* Clauses are regularly scrubbed from variables that have been assigned
* Preliminary blocked-clause elimination is used to remove pure literals
* Distinct subproblems are regularly searched for and detected. These
subproblems and solved with subsolvers. As a side-ntoe, this eliminates
the original theoretical need for phase-saving (enabling the random
flipping of phase, which is also used)
* xor-clause subsumption is regularly performed
* So-called dependent variables are removed along with their xor-clauses.
This means that variables that only occur in one xor-clause and in no
other clause are removed along with the XOR clause. Once the solving has
finished, this xor-clause is re-introduced and a suitable value for the
variable is found to satisfy the XOR.
* Failed variable probing with both-propagated and binary XOR detection.
All variables are successively propagated both to TRUE and FALSE. If one
of these branches fails, the variable is assigned the other branch.
If none fails, but the intersection of assignments is non-empty, those
assignments are made. Essentially the same is done to non-binary XOR-s:
if both v and !v propagate a given binary XOR, that XOR is learnt.
* Designed to work as a library and as a drop-in replacement for MiniSat
ver 2.3.2 -- 28/12/2009
* further ints have been replaced with uints
* ZLIB can now be disabled
* Visual C++ 2008 can now compile the sources
* Statistics generation is much faster
(thanks to Martin Maurer for spotting this)
ver 2.3.0 -- 17/12/2009
* binary learnts are converted to 2-long xors if possible, and eliminated
* lots of heuristics tuning
* Cleanclauses is now default instead of removeSatisfied in simplify()
* Stable in case used as a library
* Lots of regression tests added
* Cleaner logging
* ints have been replaced with uints (less warnings with -Wall)
* a lot of speedups for gauss -- packed, multi-matrix representation
ver 2.2 -- 20/11/2009
* xor-clause finding
* matrix finding
* var-replacing
* heuristics to disable gauss
* much better+cleaner stats generation (e.g. fcopy.cpp removed)
* lots of bug-fixing
* satelite added, with cryptominisat_ext.sh as a wrapper script
ver 2.1.1 -- 30/10/2009
* Learnt clause distribution stats
* Added regression testing
ver 2.1.0 -- 28/10/2009
* hand-made (non-GPL Bignum) packed representation of both matrix' rows
* removed dependency on GPL Bignum library
ver 2.0.1 -- 24/10/2009
* Added Gaussian elimination
ver 1.2.6 -- 24/10/2009
* Corrected unitialised maxRestarts
ver 1.2.6 -- 24/10/2009
* Corrected unitialised maxRestarts
ver 1.2.5 -- 24/10/2009
* Maximum restarts can be configured
* Better verbose debug printing
ver 1.2.4 -- 22/10/2009
* CryptoMiniSat is printed as the first line of the program
(instead of "This is MiniSat 2.0 beta")
ver 1.2.3 -- 22/10/2009
* better README file
* better use of the automake autoconf toolchain
ver 1.2.2 -- 22/10/2009
* phase saving added (thank you, glucose solver team)
* better printing of statistics
* better explanation of statistics
* accept 'v' and 'var', 'g' and 'group'
* better parsing of 'v','var' and 'g','group'
* don't allow too long group and variable names
* branch length distribution added
* better Makefile.cvs
* cmake option added
* updated INSTALL instructions
* '-march=native' is default when using cmake
ver 1.1 -- 29/04/2009
* Renamed to CryptoMiniSat
ver 1.0 -- 15/04/2009
* Some updated statistics! Now average rank of guessed var is shown

152
packages/bee/cryptominisat-2.5.1/README vendored Executable file
View File

@ -0,0 +1,152 @@
CryptoMiniSat integrates a lot of advancements relative to MiniSat.
You can find these under the NEWS file. Here, we will explain how to
use the xor-clause and logging facilities of CryptoMiniSat:
* Xor-clauses. If you want to express a xor, e.g.
"var1 + var2 + !var3 = true"
then you simply need to put into the sat file the line:
"x1 2 -3 0". The "x" in
front of the line means that this is a xor-clause clause.
* Clause grouping. Usage: "-grouping" in command line. Used to give a
name to each and every clause. Useful if you wish to create meaningful
statistics. To use it, you must have after each and every clause a line
"c g GROUPNUM NAME".
Example:
161 18 20 -22 0
c g 11 nice name
161 -18 -20 0
c g 11 nice name
141 68 -66 74 0
c g 234 somewhat nicer name
These are three clauses. The first two belong to group 11, which has
the name "nice name". The third clause belongs to group 234, and is
named "somewhat nicer name". Grouping is important once you need to have
more than one clause to express the same concept. I.e. if you were describing
an equation in ANF (Algebraic Normal Form), you could easily give the same
group to the different clauses representing the same equation. You can find
examples of the usage in the "satfile" file under the "bulid" directory
* Variable naming. In the CNF file, you have to add a line describing the
name of each variable. The lines must follow the pattern
"c v VAR NAME"
for each variable. Example:
c v 36 sr[0][35] (real unknown)
This sets variable number 36 to be named "sr[0][35] (real unknown)".
You can find examples of this in the "satfile" under the "build"
directory. I personally add the definition of all variables at the
end of my CNF file.s
* Advanced statistics. The output of the sample satfile that is under
"/optimized/src/satfile" if running with statistics:
--------------
soos@charmille:$ ./cryptominisat -stats -grouping satfile
[..printed data..]
+===========================================================+
||********* STATS FOR THIS RESTART BEGIN ******************||
+===========================================================+
+-----------------------------------------------------------+
| No. times variable branched on |
|var var name no. times |
+-----------------------------------------------------------+
|54 sr[0][65](real unknown) 1608 |
|45 sr[0][49](real unknown) 1480 |
|82 sr[0][43](real unknown) 1461 |
|66 sr[0][54](real unknown) 1420 |
|195 sr[0][59](real unknown) 1407 |
|218 sr[0][69](real unknown) 1318 |
|88 sr[0][57](real unknown) 1307 |
|223 sr[0][51](real unknown) 1260 |
|426 sr[0][70](real unknown) 1201 |
|236 sr[0][47](real unknown) 1149 |
|83 sr[0][56](real unknown) 1118 |
|43 sr[0][45](real unknown) 1050 |
|387 sr[0][74](real unknown) 1014 |
|46 sr[0][72](real unknown) 1012 |
|378 sr[0][55](real unknown) 975 |
|349 sr[0][58](real unknown) 890 |
|9 sr[0][66](real unknown) 889 |
|279 sr[0][44](real unknown) 841 |
|108 sr[0][61](real unknown) 841 |
|401 sr[0][42](real unknown) 820 |
+-----------------------------------------------------------+
This list means that variable 54, which represents the 65th bit
in the shift register has been branched upon 1608 times during the
solving. This, by the way, is logical, as we were trying to solve the
state of the stream cipher, which is of course the shift register's
state.
The statistics also gives you the following for each restart
(minisat does re-starts every so often, these are the lines that
appear one after the other when you are running it):
+-----------------------------------------------------------+
| Advanced statistics |
+-----------------------------------------------------------+
|No. branches visited 15585 |
|Avg. branch depth 84.81 |
|No. decisions 32755 |
|No. propagations 1151570 |
|sum decisions on branches/no. branches |
| (in a given branch, what is the avg. |
| no. of decisions?) 8.518 |
|sum propagations on branches/no. branches |
| (in a given branch, what is the |
| avg. no. of propagations?) 76.29 |
+-----------------------------------------------------------+
You can see, for example, that 8.52 + 76.29 = 84.81 so things add up.
* "-randomize=XXX" randomizes the clause order and initial variable pick order.
You can measure how much time it takes for minisat on average to solve a
problem written down in a SAT file. Useful to calculate average speed of a
given problem instance. Just run the problem with multiple "-randomize=xx"
numbers and make the average.
* If you create a directory "proofs", and then you execute
"./minisat -proof-log -grouping satfile"
then CryptoMiniSat produces a set of files, named "NUM-proofX.dot" in the
"proofs" directory, where NUM is a fixed number for a given run, and X is
the restart number. For the example "satfile" under the "build" directory:
$ ls proofs/
7491-proof0.dot
7491-proof1.dot
7491-proof2.dot
[...]
First you need to get graphviz (free software, available form
http://www.graphviz.org/Download..php for both windows and linux). If you
now issue "dot -Tsvg 7491-proof1.dot > proof1.svg" and wait a couple of
minutes, you get a file "proof1.svg" that contains what happened at the 1st
restart (which is not really a restart, it's the first run: the 0th restart
is the inserting of clauses). This SVG file is included into this email
(zipped). You can view it only with a very good SVG-reader, like the
free-software inkscape ( http://www.inkscape.org/download/?lang=en ),
available under windows and linux.
* There is an option to have a LOT of debugging output from CryptoMiniSat. To
turn it on, define VERBOSE_DEBUG. See the "INSTALL" file how to do this.
After re-compilation, run CryptoMiniSat as usual. This will give you a LOT
of information regarding what happens inside CryptoMiniSat. Propagations,
cancellations, conflicts, conflict clauses, etc. To handle the amount of
information, I suggest you to run CryptoMiniSat as:
"./cryptominisat satfile > debug.txt"
and then open the "debug.txt" with your favourite text editor.
(I use "less" if the file is gigabyte-sized files)

View File

@ -0,0 +1,187 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef BITARRAY_H
#define BITARRAY_H
//#define DEBUG_BITARRAY
#include <string.h>
#include <assert.h>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
class BitArray
{
public:
BitArray() :
size(0)
, mp(NULL)
{
}
BitArray(const BitArray& b) :
size(b.size)
{
mp = new uint64_t[size];
memcpy(mp, b.mp, sizeof(uint64_t)*size);
}
BitArray& operator=(const BitArray& b)
{
if (size != b.size) {
delete[] mp;
size = b.size;
mp = new uint64_t[size];
}
memcpy(mp, b.mp, sizeof(uint64_t)*size);
return *this;
}
BitArray& operator&=(const BitArray& b)
{
assert(size == b.size);
uint64_t* t1 = mp;
uint64_t* t2 = b.mp;
for (uint64_t i = 0; i < size; i++) {
*t1 &= *t2;
t1++;
t2++;
}
return *this;
}
const bool nothingInCommon(const BitArray& b) const
{
assert(size == b.size);
const uint64_t* t1 = mp;
const uint64_t* t2 = b.mp;
for (uint64_t i = 0; i < size; i++) {
if ((*t1)&(*t2)) return false;
t1++;
t2++;
}
return true;
}
BitArray& removeThese(const BitArray& b)
{
assert(size == b.size);
uint64_t* t1 = mp;
uint64_t* t2 = b.mp;
for (uint64_t i = 0; i < size; i++) {
*t1 &= ~(*t2);
t1++;
t2++;
}
return *this;
}
template<class T>
BitArray& removeThese(const T& rem)
{
for (uint32_t i = 0; i < rem.size(); i++) {
clearBit(rem[i]);
}
return *this;
}
void resize(uint _size, const bool fill)
{
_size = _size/64 + (bool)(_size%64);
if (size != _size) {
delete[] mp;
size = _size;
mp = new uint64_t[size];
}
if (fill) setOne();
else setZero();
}
~BitArray()
{
delete[] mp;
}
inline const bool isZero() const
{
const uint64_t* mp2 = (const uint64_t*)mp;
for (uint i = 0; i < size; i++) {
if (mp2[i]) return false;
}
return true;
}
inline void setZero()
{
memset(mp, 0, size*sizeof(uint64_t));
}
inline void setOne()
{
memset(mp, 0, size*sizeof(uint64_t));
}
inline void clearBit(const uint i)
{
#ifdef DEBUG_BITARRAY
assert(size*64 > i);
#endif
mp[i/64] &= ~((uint64_t)1 << (i%64));
}
inline void setBit(const uint i)
{
#ifdef DEBUG_BITARRAY
assert(size*64 > i);
#endif
mp[i/64] |= ((uint64_t)1 << (i%64));
}
inline const bool operator[](const uint& i) const
{
#ifdef DEBUG_BITARRAY
assert(size*64 > i);
#endif
return (mp[i/64] >> (i%64)) & 1;
}
inline const uint getSize() const
{
return size*64;
}
private:
uint size;
uint64_t* mp;
};
#endif //BITARRAY_H

View File

@ -0,0 +1,82 @@
/*****************************************************************************************[Queue.h]
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
2008 - Gilles Audemard, Laurent Simon
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#ifndef BoundedQueue_h
#define BoundedQueue_h
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "Vec.h"
//=================================================================================================
template <class T>
class bqueue {
vec<T> elems;
int first;
int last;
uint64_t sumofqueue;
int maxsize;
int queuesize; // Number of current elements (must be < maxsize !)
public:
bqueue(void) : first(0), last(0), sumofqueue(0), maxsize(0), queuesize(0) { }
void initSize(int size) {growTo(size);} // Init size of bounded size queue
void push(T x) {
if (queuesize==maxsize) {
assert(last==first); // The queue is full, next value to enter will replace oldest one
sumofqueue -= elems[last];
if ((++last) == maxsize) last = 0;
} else
queuesize++;
sumofqueue += x;
elems[first] = x;
if ((++first) == maxsize) first = 0;
}
T peek() { assert(queuesize>0); return elems[last]; }
void pop() {sumofqueue-=elems[last]; queuesize--; if ((++last) == maxsize) last = 0;}
uint64_t getsum() const {return sumofqueue;}
uint32_t getavg() const {return (uint64_t)sumofqueue/(uint64_t)queuesize;}
int isvalid() const {return (queuesize==maxsize);}
void growTo(int size) {
elems.growTo(size);
first=0; maxsize=size; queuesize = 0;
for(int i=0;i<size;i++) elems[i]=0;
}
void fastclear() {first = 0; last = 0; queuesize=0; sumofqueue=0;} // to be called after restarts... Discard the queue
int size(void) { return queuesize; }
void clear(bool dealloc = false) { elems.clear(dealloc); first = 0; maxsize=0; queuesize=0;sumofqueue=0;}
};
//=================================================================================================
#endif

View File

@ -0,0 +1,41 @@
include_directories(${cryptoms_SOURCE_DIR}/mtl)
include_directories(${cryptoms_SOURCE_DIR}/Solver)
include_directories(${cryptoms_SOURCE_DIR}/MTRand)
# cmake_minimum_required( VERSION 2.6 FATAL_ERROR )
# find_package( Boost 1.34 COMPONENTS REQUIRED thread )
# link_directories ( ${Boost_LIBRARY_DIRS} )
# include_directories ( ${Boost_INCLUDE_DIRS} )
add_executable(cryptominisat Main.C)
target_link_libraries(cryptominisat
cryptominisatlib
${ZLIB_LIBRARY}
# ${Boost_LIBRARIES}
# ${CMAKE_THREAD_LIBS_INIT}
)
add_library(cryptominisatlib
Logger.cpp
Solver.cpp
Gaussian.cpp
PackedRow.cpp
XorFinder.cpp
MatrixFinder.cpp
VarReplacer.cpp
FindUndef.cpp
ClauseCleaner.cpp
RestartTypeChooser.cpp
SmallPtr.cpp
Clause.cpp
FailedVarSearcher.cpp
PartFinder.cpp
Subsumer.cpp
PartHandler.cpp
XorSubsumer.cpp
StateSaver.cpp
Clause.cpp
)

131
packages/bee/cryptominisat-2.5.1/Solver/CSet.h vendored Executable file
View File

@ -0,0 +1,131 @@
/**************************************************************************************************
From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
**************************************************************************************************/
#ifndef CSET_H
#define CSET_H
#include "Vec.h"
#include <limits>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
class Clause;
template <class T>
uint32_t calcAbstraction(const T& ps) {
uint32_t abstraction = 0;
for (uint32_t i = 0; i != ps.size(); i++)
abstraction |= 1 << (ps[i].toInt() & 31);
return abstraction;
}
//#pragma pack(push)
//#pragma pack(1)
class ClauseSimp
{
public:
ClauseSimp(Clause* c, const uint32_t _index) :
clause(c)
, index(_index)
{}
Clause* clause;
uint32_t index;
};
//#pragma pack(pop)
class CSet {
vec<uint32_t> where; // Map clause ID to position in 'which'.
vec<ClauseSimp> which; // List of clauses (for fast iteration). May contain 'Clause_NULL'.
vec<uint32_t> free; // List of positions holding 'Clause_NULL'.
public:
//ClauseSimp& operator [] (uint32_t index) { return which[index]; }
void reserve(uint32_t size) { where.reserve(size);}
uint32_t size(void) const { return which.size(); }
uint32_t nElems(void) const { return which.size() - free.size(); }
bool add(const ClauseSimp& c) {
assert(c.clause != NULL);
where.growTo(c.index+1, std::numeric_limits<uint32_t>::max());
if (where[c.index] != std::numeric_limits<uint32_t>::max()) {
return true;
}
if (free.size() > 0){
where[c.index] = free.last();
which[free.last()] = c;
free.pop();
}else{
where[c.index] = which.size();
which.push(c);
}
return false;
}
bool exclude(const ClauseSimp& c) {
assert(c.clause != NULL);
if (c.index >= where.size() || where[c.index] == std::numeric_limits<uint32_t>::max()) {
//not inside
return false;
}
free.push(where[c.index]);
which[where[c.index]].clause = NULL;
where[c.index] = std::numeric_limits<uint32_t>::max();
return true;
}
void clear(void) {
for (uint32_t i = 0; i < which.size(); i++) {
if (which[i].clause != NULL) {
where[which[i].index] = std::numeric_limits<uint32_t>::max();
}
}
which.clear();
free.clear();
}
class iterator
{
public:
iterator(ClauseSimp* _it) :
it(_it)
{}
void operator++()
{
it++;
}
const bool operator!=(const iterator& iter) const
{
return (it != iter.it);;
}
ClauseSimp& operator*() {
return *it;
}
ClauseSimp*& operator->() {
return it;
}
private:
ClauseSimp* it;
};
iterator begin()
{
return iterator(which.getData());
}
iterator end()
{
return iterator(which.getData() + which.size());
}
};
#endif //CSET_H

View File

@ -0,0 +1,9 @@
#include "Clause.h"
#ifdef USE_POOLS
#ifdef USE_4POOLS
boost::pool<> clausePoolQuad(sizeof(Clause) + 5*sizeof(Lit));
#endif //USE_4POOLS
boost::pool<> clausePoolTri(sizeof(Clause) + 3*sizeof(Lit));
boost::pool<> clausePoolBin(sizeof(Clause) + 2*sizeof(Lit));
#endif //USE_POOLS

View File

@ -0,0 +1,489 @@
/***********************************************************************************[SolverTypes.h]
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#ifndef CLAUSE_H
#define CLAUSE_H
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include <cstdio>
#include <vector>
#include <sys/types.h>
#include "Vec.h"
#include "SolverTypes.h"
#include "PackedRow.h"
#include "constants.h"
#include "SmallPtr.h"
#ifdef USE_POOLS
#include <boost/pool/pool.hpp>
#endif //USE_POOLS
#ifndef uint
#define uint unsigned int
#endif
//#define USE_4POOLS
using std::vector;
//=================================================================================================
// Clause -- a simple class for representing a clause:
class MatrixFinder;
class Clause
{
protected:
#ifdef STATS_NEEDED
uint group;
#endif
uint32_t isLearnt:1;
uint32_t strenghtened:1;
uint32_t varChanged:1;
uint32_t sorted:1;
uint32_t invertedXor:1;
uint32_t isXorClause:1;
uint32_t subsume0Done:1;
uint32_t isRemoved:1;
#ifdef USE_POOLS
uint32_t wasTriOriginallyInt:1;
uint32_t wasBinOriginallyInt:1;
#ifdef USE_4POOLS
uint32_t wasQuadOriginallyInt:1;
#endif //USE_4POOLS
#endif //USE_POOLS
uint32_t mySize:20;
union {uint32_t act; uint32_t abst;} extra;
float oldActivityInter;
#ifdef _MSC_VER
Lit data[1];
#else
Lit data[0];
#endif //_MSC_VER
#ifdef _MSC_VER
public:
#endif //_MSC_VER
template<class V>
Clause(const V& ps, const uint _group, const bool learnt)
{
isXorClause = false;
strenghtened = false;
sorted = false;
varChanged = true;
subsume0Done = false;
mySize = ps.size();
isLearnt = learnt;
isRemoved = false;
setGroup(_group);
#ifdef USE_POOLS
setAllocSize();
#endif //USE_POOLS
for (uint i = 0; i < ps.size(); i++) data[i] = ps[i];
if (learnt) {
extra.act = 0;
oldActivityInter = 0;
} else
calcAbstraction();
}
public:
#ifndef _MSC_VER
// -- use this function instead:
template<class T>
friend Clause* Clause_new(const T& ps, const uint group, const bool learnt);
friend Clause* Clause_new(Clause& c);
#endif //_MSC_VER
const uint size () const {
return mySize;
}
void resize (const uint size) {
mySize = size;
}
void shrink (const uint i) {
assert(i <= size());
mySize -= i;
}
void pop () {
shrink(1);
}
const bool isXor () {
return isXorClause;
}
const bool learnt () const {
return isLearnt;
}
float& oldActivity () {
return oldActivityInter;
}
const float& oldActivity () const {
return oldActivityInter;
}
const bool getStrenghtened() const {
return strenghtened;
}
void setStrenghtened() {
strenghtened = true;
sorted = false;
subsume0Done = false;
}
void unsetStrenghtened() {
strenghtened = false;
}
const bool getVarChanged() const {
return varChanged;
}
void setVarChanged() {
varChanged = true;
sorted = false;
subsume0Done = false;
}
void unsetVarChanged() {
varChanged = false;
}
const bool getSorted() const {
return sorted;
}
void setSorted() {
sorted = true;
}
void setUnsorted() {
sorted = false;
}
void subsume0Finished() {
subsume0Done = 1;
}
const bool subsume0IsFinished() {
return subsume0Done;
}
Lit& operator [] (uint32_t i) {
return data[i];
}
const Lit& operator [] (uint32_t i) const {
return data[i];
}
void setActivity(uint32_t i) {
extra.act = i;
}
const uint32_t& activity () const {
return extra.act;
}
void makeNonLearnt() {
assert(isLearnt);
isLearnt = false;
calcAbstraction();
}
void makeLearnt(const uint32_t newActivity) {
extra.act = newActivity;
oldActivityInter = 0;
isLearnt = true;
}
inline void strengthen(const Lit p)
{
remove(*this, p);
sorted = false;
calcAbstraction();
}
void calcAbstraction() {
assert(!learnt());
extra.abst = 0;
for (uint32_t i = 0; i != size(); i++)
extra.abst |= 1 << (data[i].toInt() & 31);
}
uint32_t getAbst()
{
return extra.abst;
}
const Lit* getData () const {
return data;
}
Lit* getData () {
return data;
}
const Lit* getDataEnd () const {
return data+size();
}
Lit* getDataEnd () {
return data+size();
}
void print(FILE* to = stdout) {
plainPrint(to);
fprintf(to, "c clause learnt %s group %d act %d oldAct %f\n", (learnt() ? "yes" : "no"), getGroup(), activity(), oldActivity());
}
void plainPrint(FILE* to = stdout) const {
for (uint i = 0; i < size(); i++) {
if (data[i].sign()) fprintf(to, "-");
fprintf(to, "%d ", data[i].var() + 1);
}
fprintf(to, "0\n");
}
#ifdef STATS_NEEDED
const uint32_t getGroup() const
{
return group;
}
void setGroup(const uint32_t _group)
{
group = _group;
}
#else
const uint getGroup() const
{
return 0;
}
void setGroup(const uint32_t _group)
{
return;
}
#endif //STATS_NEEDED
void setRemoved() {
isRemoved = true;
}
const bool removed() const {
return isRemoved;
}
#ifdef USE_POOLS
const bool wasTriOriginally() const
{
return wasTriOriginallyInt;
}
const bool wasBinOriginally() const
{
return wasBinOriginallyInt;
}
#ifdef USE_4POOLS
const bool wasQuadOriginally() const
{
return wasQuadOriginallyInt;
}
#endif //USE_4POOLS
void setAllocSize()
{
wasTriOriginallyInt = false;
wasBinOriginallyInt = false;
#ifdef USE_4POOLS
wasQuadOriginallyInt = false;
#endif //USE_4POOLS
switch(size()) {
case 2:
wasBinOriginallyInt = true;
break;
case 3:
wasTriOriginallyInt = true;
break;
#ifdef USE_4POOLS
case 4:
wasQuadOriginallyInt = true;
break;
case 5:
wasQuadOriginallyInt = true;
break;
#endif //USE_4POOLS
}
}
#endif //USE_POOLS
};
class XorClause : public Clause
{
#ifdef _MSC_VER
public:
#else //_MSC_VER
protected:
#endif //_MSC_VER
// NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
template<class V>
XorClause(const V& ps, const bool inverted, const uint _group) :
Clause(ps, _group, false)
{
invertedXor = inverted;
isXorClause = true;
calcXorAbstraction();
}
public:
#ifndef _MSC_VER
// -- use this function instead:
template<class V>
friend XorClause* XorClause_new(const V& ps, const bool inverted, const uint group);
#endif //_MSC_VER
inline bool xor_clause_inverted() const
{
return invertedXor;
}
inline void invert(bool b)
{
invertedXor ^= b;
}
void calcXorAbstraction() {
extra.abst = 0;
for (uint32_t i = 0; i != size(); i++)
extra.abst |= 1 << (data[i].var() & 31);
}
void print() {
printf("XOR Clause group: %d, size: %d, learnt:%d, lits:\"", getGroup(), size(), learnt());
plainPrint();
}
void plainPrint(FILE* to = stdout) const {
fprintf(to, "x");
if (xor_clause_inverted())
printf("-");
for (uint i = 0; i < size(); i++) {
fprintf(to, "%d ", data[i].var() + 1);
}
fprintf(to, "0\n");
}
friend class MatrixFinder;
};
#ifdef USE_POOLS
extern boost::pool<> clausePoolTri;
extern boost::pool<> clausePoolBin;
#ifdef USE_4POOLS
extern boost::pool<> clausePoolQuad;
#endif //USE_4POOLS
#endif //USE_POOLS
template<class T>
inline void* allocEnough(const T& ps)
{
void* mem;
switch(ps.size()) {
#ifdef USE_POOLS
case 2:
mem = clausePoolBin.malloc();
break;
case 3:
mem = clausePoolTri.malloc();
break;
#ifdef USE_4POOLS
case 4:
mem = clausePoolQuad.malloc();
break;
case 5:
mem = clausePoolQuad.malloc();
break;
#endif //USE_4POOLS
#endif //USE_POOLS
default:
mem = malloc(sizeof(Clause) + sizeof(Lit)*(ps.size()));
break;
}
return mem;
}
template<class T>
Clause* Clause_new(const T& ps, const uint group, const bool learnt = false)
{
void* mem = allocEnough(ps);
Clause* real= new (mem) Clause(ps, group, learnt);
return real;
}
template<class T>
XorClause* XorClause_new(const T& ps, const bool inverted, const uint group)
{
void* mem = allocEnough(ps);
XorClause* real= new (mem) XorClause(ps, inverted, group);
return real;
}
inline Clause* Clause_new(Clause& c)
{
void* mem = allocEnough(c);
//Clause* real= new (mem) Clause(ps, group, learnt);
memcpy(mem, &c, sizeof(Clause)+sizeof(Lit)*c.size());
Clause& c2 = *(Clause*)mem;
#ifdef USE_POOLS
c2.setAllocSize();
#endif //USE_POOLS
return &c2;
}
inline void clauseFree(Clause* c)
{
#ifdef USE_POOLS
if (c->wasTriOriginally())
clausePoolTri.free(c);
else if (c->wasBinOriginally())
clausePoolBin.free(c);
#ifdef USE_4POOLS
else if (c->wasQuadOriginally())
clausePoolQuad.free(c);
#endif //USE_4POOLS
else
#endif //USE_POOLS
free(c);
}
#ifdef _MSC_VER
typedef Clause* ClausePtr;
typedef XorClause* XorClausePtr;
#else
typedef sptr<Clause> ClausePtr;
typedef sptr<XorClause> XorClausePtr;
#endif //_MSC_VER
#pragma pack(push)
#pragma pack(1)
class WatchedBin {
public:
WatchedBin(Clause *_clause, Lit _impliedLit) : clause(_clause), impliedLit(_impliedLit) {};
ClausePtr clause;
Lit impliedLit;
};
class Watched {
public:
Watched(Clause *_clause, Lit _blockedLit) : clause(_clause), blockedLit(_blockedLit) {};
ClausePtr clause;
Lit blockedLit;
};
#pragma pack(pop)
#endif //CLAUSE_H

View File

@ -0,0 +1,416 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "ClauseCleaner.h"
#include "VarReplacer.h"
#ifdef _MSC_VER
#define __builtin_prefetch(a,b,c)
#endif //_MSC_VER
//#define DEBUG_CLEAN
//#define VERBOSE_DEBUG
ClauseCleaner::ClauseCleaner(Solver& _solver) :
solver(_solver)
{
for (uint i = 0; i < 6; i++) {
lastNumUnitarySat[i] = solver.get_unitary_learnts_num();
lastNumUnitaryClean[i] = solver.get_unitary_learnts_num();
}
}
void ClauseCleaner::removeSatisfied(vec<XorClause*>& cs, ClauseSetType type, const uint limit)
{
#ifdef DEBUG_CLEAN
assert(solver.decisionLevel() == 0);
#endif
if (lastNumUnitarySat[type] + limit >= solver.get_unitary_learnts_num())
return;
uint32_t i,j;
for (i = j = 0; i < cs.size(); i++) {
if (satisfied(*cs[i]))
solver.removeClause(*cs[i]);
else
cs[j++] = cs[i];
}
cs.shrink(i - j);
lastNumUnitarySat[type] = solver.get_unitary_learnts_num();
}
void ClauseCleaner::removeSatisfied(vec<Clause*>& cs, ClauseSetType type, const uint limit)
{
#ifdef DEBUG_CLEAN
assert(solver.decisionLevel() == 0);
#endif
if (lastNumUnitarySat[type] + limit >= solver.get_unitary_learnts_num())
return;
Clause **i,**j, **end;
for (i = j = cs.getData(), end = i + cs.size(); i != end; i++) {
if (i+1 != end)
__builtin_prefetch(*(i+1), 0, 0);
if (satisfied(**i))
solver.removeClause(**i);
else
*j++ = *i;
}
cs.shrink(i - j);
lastNumUnitarySat[type] = solver.get_unitary_learnts_num();
}
void ClauseCleaner::cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint limit)
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
return;
#ifdef VERBOSE_DEBUG
std::cout << "Cleaning " << (type==binaryClauses ? "binaryClauses" : "normal clauses" ) << std::endl;
#endif //VERBOSE_DEBUG
Clause **s, **ss, **end;
for (s = ss = cs.getData(), end = s + cs.size(); s != end;) {
if (s+1 != end)
__builtin_prefetch(*(s+1), 1, 0);
if (cleanClause(*s)) {
clauseFree(*s);
s++;
} else if (type != ClauseCleaner::binaryClauses && (*s)->size() == 2) {
solver.binaryClauses.push(*s);
solver.becameBinary++;
s++;
} else {
*ss++ = *s++;
}
}
cs.shrink(s-ss);
lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
#ifdef VERBOSE_DEBUG
cout << "cleanClauses(Clause) useful ?? Removed: " << s-ss << endl;
#endif
}
inline const bool ClauseCleaner::cleanClause(Clause*& cc)
{
Clause& c = *cc;
Lit origLit1 = c[0];
Lit origLit2 = c[1];
uint32_t origSize = c.size();
Lit *i, *j, *end;
for (i = j = c.getData(), end = i + c.size(); i != end; i++) {
lbool val = solver.value(*i);
if (val == l_Undef) {
*j++ = *i;
continue;
}
if (val == l_True) {
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
return true;
}
}
c.shrink(i-j);
if (i != j) {
c.setStrenghtened();
if (c.size() == 2) {
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
Clause *c2 = Clause_new(c);
clauseFree(&c);
cc = c2;
solver.attachClause(*c2);
/*} else if (c.size() == 3) {
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
Clause *c2 = Clause_new(c);
clauseFree(&c);
cc = c2;
solver.attachClause(*c2);*/
} else {
if (c.learnt())
solver.learnts_literals -= i-j;
else
solver.clauses_literals -= i-j;
}
}
return false;
}
void ClauseCleaner::cleanClauses(vec<XorClause*>& cs, ClauseSetType type, const uint limit)
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
return;
XorClause **s, **ss, **end;
for (s = ss = cs.getData(), end = s + cs.size(); s != end; s++) {
if (s+1 != end)
__builtin_prefetch(*(s+1), 1, 0);
#ifdef DEBUG_ATTACH
assert(find(solver.xorwatches[(**s)[0].var()], *s));
assert(find(solver.xorwatches[(**s)[1].var()], *s));
if (solver.assigns[(**s)[0].var()]!=l_Undef || solver.assigns[(**s)[1].var()]!=l_Undef) {
satisfied(**s);
}
#endif //DEBUG_ATTACH
if (cleanClause(**s)) {
solver.freeLater.push(*s);
(*s)->setRemoved();
} else {
#ifdef DEBUG_ATTACH
assert(find(solver.xorwatches[(**s)[0].var()], *s));
assert(find(solver.xorwatches[(**s)[1].var()], *s));
#endif //DEBUG_ATTACH
*ss++ = *s;
}
}
cs.shrink(s-ss);
lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
#ifdef VERBOSE_DEBUG
cout << "cleanClauses(XorClause) useful: ?? Removed: " << s-ss << endl;
#endif
}
inline const bool ClauseCleaner::cleanClause(XorClause& c)
{
Lit *i, *j, *end;
Var origVar1 = c[0].var();
Var origVar2 = c[1].var();
uint32_t origSize = c.size();
for (i = j = c.getData(), end = i + c.size(); i != end; i++) {
const lbool& val = solver.assigns[i->var()];
if (val.isUndef()) {
*j = *i;
j++;
} else c.invert(val.getBool());
}
c.shrink(i-j);
assert(c.size() != 1);
switch (c.size()) {
case 0: {
solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
return true;
}
case 2: {
c[0] = c[0].unsign();
c[1] = c[1].unsign();
solver.varReplacer->replace(c, c.xor_clause_inverted(), c.getGroup());
solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
return true;
}
default: {
if (i-j > 0) {
c.setStrenghtened();
solver.clauses_literals -= i-j;
}
return false;
}
}
assert(false);
return false;
}
void ClauseCleaner::cleanClausesBewareNULL(vec<ClauseSimp>& cs, ClauseCleaner::ClauseSetType type, Subsumer& subs, const uint limit)
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
return;
ClauseSimp *s, *end;
for (s = cs.getData(), end = s + cs.size(); s != end; s++) {
if (s+1 != end)
__builtin_prefetch((s+1)->clause, 1, 0);
if (s->clause == NULL)
continue;
if (cleanClauseBewareNULL(*s, subs)) {
continue;
} else if (s->clause->size() == 2)
solver.becameBinary++;
}
lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
}
inline const bool ClauseCleaner::cleanClauseBewareNULL(ClauseSimp cc, Subsumer& subs)
{
Clause& c = *cc.clause;
vec<Lit> origClause(c.size());
memcpy(origClause.getData(), c.getData(), sizeof(Lit)*c.size());
Lit *i, *j, *end;
for (i = j = c.getData(), end = i + c.size(); i != end; i++) {
lbool val = solver.value(*i);
if (val == l_Undef) {
*j++ = *i;
continue;
}
if (val == l_True) {
subs.unlinkModifiedClause(origClause, cc);
clauseFree(cc.clause);
return true;
}
}
if (i != j) {
c.setStrenghtened();
if (origClause.size() > 2 && origClause.size()-(i-j) == 2) {
subs.unlinkModifiedClause(origClause, cc);
subs.clauses[cc.index] = cc;
c.shrink(i-j);
solver.attachClause(c);
subs.linkInAlreadyClause(cc);
} else {
c.shrink(i-j);
subs.unlinkModifiedClauseNoDetachNoNULL(origClause, cc);
subs.linkInAlreadyClause(cc);
if (c.learnt())
solver.learnts_literals -= i-j;
else
solver.clauses_literals -= i-j;
}
c.calcAbstraction();
subs.updateClause(cc);
}
return false;
}
void ClauseCleaner::cleanXorClausesBewareNULL(vec<XorClauseSimp>& cs, ClauseCleaner::ClauseSetType type, XorSubsumer& subs, const uint limit)
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
return;
XorClauseSimp *s, *end;
for (s = cs.getData(), end = s + cs.size(); s != end; s++) {
if (s+1 != end)
__builtin_prefetch((s+1)->clause, 1, 0);
if (s->clause == NULL)
continue;
cleanXorClauseBewareNULL(*s, subs);
}
lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
}
inline const bool ClauseCleaner::cleanXorClauseBewareNULL(XorClauseSimp cc, XorSubsumer& subs)
{
XorClause& c = *cc.clause;
vec<Lit> origClause(c.size());
memcpy(origClause.getData(), c.getData(), sizeof(Lit)*c.size());
Lit *i, *j, *end;
for (i = j = c.getData(), end = i + c.size(); i != end; i++) {
const lbool& val = solver.assigns[i->var()];
if (val.isUndef()) {
*j = *i;
j++;
} else c.invert(val.getBool());
}
c.shrink(i-j);
switch(c.size()) {
case 0: {
subs.unlinkModifiedClause(origClause, cc);
clauseFree(cc.clause);
return true;
}
case 2: {
vec<Lit> ps(2);
ps[0] = c[0].unsign();
ps[1] = c[1].unsign();
solver.varReplacer->replace(ps, c.xor_clause_inverted(), c.getGroup());
subs.unlinkModifiedClause(origClause, cc);
clauseFree(cc.clause);
return true;
}
default:
if (i-j > 0) {
subs.unlinkModifiedClauseNoDetachNoNULL(origClause, cc);
subs.linkInAlreadyClause(cc);
c.calcXorAbstraction();
}
}
return false;
}
bool ClauseCleaner::satisfied(const Clause& c) const
{
for (uint i = 0; i != c.size(); i++)
if (solver.value(c[i]) == l_True)
return true;
return false;
}
bool ClauseCleaner::satisfied(const XorClause& c) const
{
bool final = c.xor_clause_inverted();
for (uint k = 0; k != c.size(); k++ ) {
const lbool& val = solver.assigns[c[k].var()];
if (val.isUndef()) return false;
final ^= val.getBool();
}
return final;
}
void ClauseCleaner::moveBinClausesToBinClauses()
{
assert(solver.decisionLevel() == 0);
assert(solver.qhead == solver.trail.size());
vec<Clause*>& cs = solver.clauses;
Clause **s, **ss, **end;
for (s = ss = cs.getData(), end = s + cs.size(); s != end; s++) {
if (s+1 != end)
__builtin_prefetch(*(s+1), 1, 0);
if ((**s).size() == 2) {
(**s).setUnsorted();
solver.binaryClauses.push(*s);
} else
*ss++ = *s;
}
cs.shrink(s-ss);
}

View File

@ -0,0 +1,75 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef CLAUSECLEANER_H
#define CLAUSECLEANER_H
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "Solver.h"
#include "Subsumer.h"
#include "XorSubsumer.h"
class ClauseCleaner
{
public:
ClauseCleaner(Solver& solver);
enum ClauseSetType {clauses, xorclauses, learnts, binaryClauses, simpClauses, xorSimpClauses};
void cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint limit = 0);
void cleanClausesBewareNULL(vec<ClauseSimp>& cs, ClauseSetType type, Subsumer& subs, const uint limit = 0);
void cleanXorClausesBewareNULL(vec<XorClauseSimp>& cs, ClauseSetType type, XorSubsumer& subs, const uint limit = 0);
const bool cleanClauseBewareNULL(ClauseSimp c, Subsumer& subs);
const bool cleanXorClauseBewareNULL(XorClauseSimp c, XorSubsumer& subs);
void cleanClauses(vec<XorClause*>& cs, ClauseSetType type, const uint limit = 0);
void removeSatisfied(vec<Clause*>& cs, ClauseSetType type, const uint limit = 0);
void removeSatisfied(vec<XorClause*>& cs, ClauseSetType type, const uint limit = 0);
void removeAndCleanAll(const bool nolimit = false);
bool satisfied(const Clause& c) const;
bool satisfied(const XorClause& c) const;
void moveBinClausesToBinClauses();
private:
const bool cleanClause(XorClause& c);
const bool cleanClause(Clause*& c);
uint lastNumUnitarySat[6];
uint lastNumUnitaryClean[6];
Solver& solver;
};
inline void ClauseCleaner::removeAndCleanAll(const bool nolimit)
{
//uint limit = std::min((uint)((double)solver.order_heap.size() * PERCENTAGECLEANCLAUSES), FIXCLEANREPLACE);
uint limit = (double)solver.order_heap.size() * PERCENTAGECLEANCLAUSES;
if (nolimit) limit = 0;
removeSatisfied(solver.binaryClauses, ClauseCleaner::binaryClauses, limit);
cleanClauses(solver.clauses, ClauseCleaner::clauses, limit);
cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses, limit);
cleanClauses(solver.learnts, ClauseCleaner::learnts, limit);
}
#endif //CLAUSECLEANER_H

View File

@ -0,0 +1,173 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef DOUBLEPACKEDROW_H
#define DOUBLEPACKEDROW_H
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include <stdlib.h>
#include "SolverTypes.h"
namespace MINISAT
{
using namespace MINISAT;
class DoublePackedRow
{
private:
class BitIter {
public:
inline void operator=(const lbool toSet)
{
val &= ~((unsigned char)3 << offset);
val |= toSet.value << offset;
}
inline operator lbool() const
{
return lbool((val >> offset) & 3);
}
inline const bool isUndef() const {
return ((lbool)*this).isUndef();
}
inline const bool isDef() const {
return ((lbool)*this).isDef();
}
inline const bool getBool() const {
return ((lbool)*this).getBool();
}
inline const bool operator==(lbool b) const {
return ((lbool)*this) == b;
}
inline const bool operator!=(lbool b) const {
return ((lbool)*this) != b;
}
const lbool operator^(const bool b) const {
return ((lbool)*this) ^ b;
}
private:
friend class DoublePackedRow;
inline BitIter(unsigned char& mp, const uint32_t _offset) :
val(mp)
, offset(_offset)
{}
unsigned char& val;
const uint32_t offset;
};
class BitIterConst {
public:
inline operator lbool() const
{
return lbool((val >> offset) & 3);
}
inline const bool isUndef() const {
return ((lbool)*this).isUndef();
}
inline const bool isDef() const {
return ((lbool)*this).isDef();
}
inline const bool getBool() const {
return ((lbool)*this).getBool();
}
inline const bool operator==(lbool b) const {
return ((lbool)*this) == b;
}
inline const bool operator!=(lbool b) const {
return ((lbool)*this) != b;
}
const lbool operator^(const bool b) const {
return ((lbool)*this) ^ b;
}
private:
friend class DoublePackedRow;
inline BitIterConst(unsigned char& mp, const uint32_t _offset) :
val(mp)
, offset(_offset)
{}
const unsigned char& val;
const uint32_t offset;
};
public:
DoublePackedRow() :
numElems(0)
, mp(NULL)
{}
uint32_t size() const
{
return numElems;
}
void growTo(const uint32_t newNumElems)
{
uint32_t oldSize = numElems/4 + (bool)(numElems % 4);
uint32_t newSize = newNumElems/4 + (bool)(newNumElems % 4);
if (oldSize >= newSize) {
numElems = std::max(newNumElems, numElems);
return;
}
mp = (unsigned char*)realloc(mp, newSize*sizeof(unsigned char));
numElems = newNumElems;
}
inline BitIter operator[](const uint32_t at)
{
return BitIter(mp[at/4], (at%4)*2);
}
inline const BitIterConst operator[](const uint32_t at) const
{
return BitIterConst(mp[at/4], (at%4)*2);
}
inline void push(const lbool val)
{
growTo(numElems+1);
(*this)[numElems-1] = val;
}
/*void clear(const uint32_t at)
{
mp[at/32] &= ~((uint64_t)3 << ((at%32)*2));
}*/
private:
Var numElems;
unsigned char *mp;
};
}; //NAMESPACE MINISAT
#endif //DOUBLEPACKEDROW_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,164 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef FAILEDVARSEARCHER_H
#define FAILEDVARSEARCHER_H
#include <set>
#include <map>
using std::map;
#include "SolverTypes.h"
#include "Clause.h"
#include "BitArray.h"
class Solver;
class TwoLongXor
{
public:
const bool operator==(const TwoLongXor& other) const
{
if (var[0] == other.var[0] && var[1] == other.var[1] && inverted == other.inverted)
return true;
return false;
}
const bool operator<(const TwoLongXor& other) const
{
if (var[0] < other.var[0]) return true;
if (var[0] > other.var[0]) return false;
if (var[1] < other.var[1]) return true;
if (var[1] > other.var[1]) return false;
if (inverted < other.inverted) return true;
if (inverted > other.inverted) return false;
return false;
}
Var var[2];
bool inverted;
};
class FailedVarSearcher {
public:
FailedVarSearcher(Solver& _solver);
const bool search(uint64_t numProps);
template<bool startUp>
const bool removeUslessBinFull();
private:
//For 2-long xor
const TwoLongXor getTwoLongXor(const XorClause& c);
void addFromSolver(const vec<XorClause*>& cs);
uint32_t newBinXor;
//For detach&re-attach (when lots of vars found)
template<class T>
void cleanAndAttachClauses(vec<T*>& cs);
const bool cleanClause(Clause& ps);
const bool cleanClause(XorClause& ps);
void completelyDetachAndReattach();
//For re-adding old removed learnt clauses
const bool readdRemovedLearnts();
void removeOldLearnts();
//Main
const bool tryBoth(const Lit lit1, const Lit lit2);
const bool tryAll(const Lit* begin, const Lit* end);
void printResults(const double myTime) const;
Solver& solver;
//Time
uint32_t extraTime;
//For failure
bool failed;
//bothprop finding
BitArray propagated;
BitArray propValue;
vec<Lit> bothSame;
//2-long xor-finding
vec<uint32_t> xorClauseSizes;
vector<vector<uint32_t> > occur;
void removeVarFromXors(const Var var);
void addVarFromXors(const Var var);
BitArray xorClauseTouched;
vec<uint32_t> investigateXor;
std::set<TwoLongXor> twoLongXors;
bool binXorFind;
uint32_t lastTrailSize;
//2-long xor-finding no.2 through
// 1) (a->b, ~a->~b) -> a=b
// 2) binary clause (a,c): (a->g, c->~g) -> a = ~c
uint32_t bothInvert;
//finding HyperBins
void addBinClauses(const Lit& lit);
BitArray unPropagatedBin;
vec<Var> propagatedVars;
void addBin(const Lit& lit1, const Lit& lit2);
void fillImplies(const Lit& lit);
BitArray myimplies;
vec<Var> myImpliesSet;
uint64_t hyperbinProps;
vector<uint32_t> litDegrees;
const bool orderLits();
uint64_t maxHyperBinProps;
uint64_t binClauseAdded;
//Remove useless binaries
template<bool startUp>
const bool fillBinImpliesMinusLast(const Lit& origLit, const Lit& lit, vec<Lit>& wrong);
template<bool startUp>
const bool removeUselessBinaries(const Lit& lit);
void removeBin(const Lit& lit1, const Lit& lit2);
vec<char> toDeleteSet;
vec<Lit> oneHopAway;
vec<Lit> wrong;
//Temporaries
vec<Lit> tmpPs;
//State for this run
uint32_t toReplaceBefore;
uint32_t origTrailSize;
uint64_t origProps;
uint32_t numFailed;
uint32_t goodBothSame;
//State between runs
bool finishedLastTimeVar;
uint32_t lastTimeWentUntilVar;
bool finishedLastTimeBin;
uint32_t lastTimeWentUntilBin;
double numPropsMultiplier;
uint32_t lastTimeFoundTruths;
uint32_t numCalls;
};
#endif //FAILEDVARSEARCHER_H

View File

@ -0,0 +1,172 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "FindUndef.h"
#include "Solver.h"
#include "VarReplacer.h"
#include <algorithm>
FindUndef::FindUndef(Solver& _solver) :
solver(_solver)
, isPotentialSum(0)
{
}
void FindUndef::fillPotential()
{
int trail = solver.decisionLevel()-1;
while(trail > 0) {
assert(trail < (int)solver.trail_lim.size());
uint at = solver.trail_lim[trail];
assert(at > 0);
Var v = solver.trail[at].var();
if (solver.assigns[v] != l_Undef) {
isPotential[v] = true;
isPotentialSum++;
}
trail--;
}
for (XorClause** it = solver.xorclauses.getData(), **end = it + solver.xorclauses.size(); it != end; it++) {
XorClause& c = **it;
for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
if (isPotential[l->var()]) {
isPotential[l->var()] = false;
isPotentialSum--;
}
assert(!solver.value(*l).isUndef());
}
}
vector<Var> replacingVars = solver.varReplacer->getReplacingVars();
for (Var *it = &replacingVars[0], *end = it + replacingVars.size(); it != end; it++) {
if (isPotential[*it]) {
isPotential[*it] = false;
isPotentialSum--;
}
}
}
void FindUndef::unboundIsPotentials()
{
for (uint i = 0; i < isPotential.size(); i++)
if (isPotential[i])
solver.assigns[i] = l_Undef;
}
void FindUndef::moveBinToNormal()
{
binPosition = solver.clauses.size();
for (uint i = 0; i != solver.binaryClauses.size(); i++)
solver.clauses.push(solver.binaryClauses[i]);
solver.binaryClauses.clear();
}
void FindUndef::moveBinFromNormal()
{
for (uint i = binPosition; i != solver.clauses.size(); i++)
solver.binaryClauses.push(solver.clauses[i]);
solver.clauses.shrink(solver.clauses.size() - binPosition);
}
const uint FindUndef::unRoll()
{
if (solver.decisionLevel() == 0) return 0;
moveBinToNormal();
dontLookAtClause.resize(solver.clauses.size(), false);
isPotential.resize(solver.nVars(), false);
fillPotential();
satisfies.resize(solver.nVars(), 0);
while(!updateTables()) {
assert(isPotentialSum > 0);
uint32_t maximum = 0;
Var v = var_Undef;
for (uint i = 0; i < isPotential.size(); i++) {
if (isPotential[i] && satisfies[i] >= maximum) {
maximum = satisfies[i];
v = i;
}
}
assert(v != var_Undef);
isPotential[v] = false;
isPotentialSum--;
std::fill(satisfies.begin(), satisfies.end(), 0);
}
unboundIsPotentials();
moveBinFromNormal();
return isPotentialSum;
}
bool FindUndef::updateTables()
{
bool allSat = true;
uint i = 0;
for (Clause** it = solver.clauses.getData(), **end = it + solver.clauses.size(); it != end; it++, i++) {
if (dontLookAtClause[i])
continue;
Clause& c = **it;
bool definitelyOK = false;
Var v = var_Undef;
uint numTrue = 0;
for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
if (solver.value(*l) == l_True) {
if (!isPotential[l->var()]) {
dontLookAtClause[i] = true;
definitelyOK = true;
break;
} else {
numTrue ++;
v = l->var();
}
}
}
if (definitelyOK)
continue;
if (numTrue == 1) {
assert(v != var_Undef);
isPotential[v] = false;
isPotentialSum--;
dontLookAtClause[i] = true;
continue;
}
//numTrue > 1
allSat = false;
for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
if (solver.value(*l) == l_True)
satisfies[l->var()]++;
}
}
return allSat;
}

View File

@ -0,0 +1,54 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef FINDUNDEF_H
#define FINDUNDEF_H
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include <vector>
using std::vector;
#include "Solver.h"
class FindUndef {
public:
FindUndef(Solver& _solver);
const uint unRoll();
private:
Solver& solver;
void moveBinToNormal();
void moveBinFromNormal();
bool updateTables();
void fillPotential();
void unboundIsPotentials();
vector<bool> dontLookAtClause; //If set to TRUE, then that clause already has only 1 lit that is true, so it can be skipped during updateFixNeed()
vector<uint32_t> satisfies;
vector<bool> isPotential;
uint32_t isPotentialSum;
uint32_t binPosition;
};
#endif //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,237 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef GAUSSIAN_H
#define GAUSSIAN_H
#include <vector>
#include <string>
#include <limits>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "SolverTypes.h"
#include "Solver.h"
#include "GaussianConfig.h"
#include "PackedMatrix.h"
#include "BitArray.h"
#ifdef VERBOSE_DEBUG
using std::vector;
using std::cout;
using std::endl;
#endif
using std::pair;
using std::string;
class Clause;
class Gaussian
{
public:
Gaussian(Solver& solver, const GaussianConfig& config, const uint matrix_no, const vector<XorClause*>& xorclauses);
~Gaussian();
const bool full_init();
llbool find_truths(vec<Lit>& learnt_clause, int& conflictC);
//statistics
void print_stats() const;
void print_matrix_stats() const;
const uint get_called() const;
const uint get_useful_prop() const;
const uint get_useful_confl() const;
const bool get_disabled() const;
const uint32_t get_unit_truths() const;
void set_disabled(const bool toset);
//functions used throughout the Solver
void canceling(const uint sublevel);
protected:
Solver& solver;
//Gauss high-level configuration
const GaussianConfig& config;
const uint matrix_no;
vector<XorClause*> xorclauses;
enum gaussian_ret {conflict, unit_conflict, propagation, unit_propagation, nothing};
gaussian_ret gaussian(Clause*& confl);
vector<Var> col_to_var_original; //Matches columns to variables
BitArray var_is_in; //variable is part of the the matrix. var_is_in's size is _minimal_ so you should check whether var_is_in.getSize() < var before issuing var_is_in[var]
uint badlevel;
class matrixset
{
public:
PackedMatrix matrix; // The matrix, updated to reflect variable assignements
BitArray var_is_set;
vector<Var> col_to_var; // col_to_var[COL] tells which variable is at a given column in the matrix. Gives unassigned_var if the COL has been zeroed (i.e. the variable assigned)
uint16_t num_rows; // number of active rows in the matrix. Unactive rows are rows that contain only zeros (and if they are conflicting, then the conflict has been treated)
uint num_cols; // number of active columns in the matrix. The columns at the end that have all be zeroed are no longer active
int least_column_changed; // when updating the matrix, this value contains the smallest column number that has been updated (Gauss elim. can start from here instead of from column 0)
vector<uint16_t> last_one_in_col; //last_one_in_col[COL] tells the last row+1 that has a '1' in that column. Used to reduce the burden of Gauss elim. (it only needs to look until that row)
vector<uint16_t> first_one_in_row;
uint removeable_cols; // the number of columns that have been zeroed out (i.e. assigned)
};
//Saved states
vector<matrixset> matrix_sets; // The matrixsets for depths 'decision_from' + 0, 'decision_from' + only_nth_gaussian_save, 'decision_from' + 2*only_nth_gaussian_save, ... 'decision_from' + 'decision_until'.
matrixset cur_matrixset; // The current matrixset, i.e. the one we are working on, or the last one we worked on
//Varibales to keep Gauss state
bool messed_matrix_vars_since_reversal;
int gauss_last_level;
vector<pair<Clause*, uint> > clauses_toclear;
bool disabled; // Gauss is disabled
//State of current elimnation
vec<uint> propagatable_rows; //used to store which rows were deemed propagatable during elimination
vector<unsigned char> changed_rows; //used to store which rows were deemed propagatable during elimination
//Statistics
uint useful_prop; //how many times Gauss gave propagation as a result
uint useful_confl; //how many times Gauss gave conflict as a result
uint called; //how many times called the Gauss
uint32_t unit_truths; //how many unitary (i.e. decisionLevel 0) truths have been found
//gauss init functions
void init(); // Initalise gauss state
void fill_matrix(matrixset& origMat); // Fills the origMat matrix
uint select_columnorder(vector<uint16_t>& var_to_col, matrixset& origMat); // Fills var_to_col and col_to_var of the origMat matrix.
//Main function
uint eliminate(matrixset& matrix, uint& conflict_row); //does the actual gaussian elimination
//matrix update functions
void update_matrix_col(matrixset& matrix, const Var x, const uint col); // Update one matrix column
void update_matrix_by_col_all(matrixset& m); // Update all columns, column-by-column (and not row-by-row)
void set_matrixset_to_cur(); // Save the current matrixset, the cur_matrixset to matrix_sets
//void update_matrix_by_row(matrixset& matrix) const;
//void update_matrix_by_col(matrixset& matrix, const uint last_level) const;
//conflict&propagation handling
gaussian_ret handle_matrix_prop_and_confl(matrixset& m, uint row, Clause*& confl);
void analyse_confl(const matrixset& m, const uint row, int32_t& maxlevel, uint& size, uint& best_row) const; // analyse conflcit to find the best conflict. Gets & returns the best one in 'maxlevel', 'size' and 'best row' (these are all UINT_MAX when calling this function first, i.e. when there is no other possible conflict to compare to the new in 'row')
gaussian_ret handle_matrix_confl(Clause*& confl, const matrixset& m, const uint size, const uint maxlevel, const uint best_row);
gaussian_ret handle_matrix_prop(matrixset& m, const uint row); // Handle matrix propagation at row 'row'
vec<Lit> tmp_clause;
//propagation&conflict handling
void cancel_until_sublevel(const uint until_sublevel); // cancels until sublevel 'until_sublevel'. The var 'until_sublevel' must NOT go over the current level. I.e. this function is ONLY for moving inside the current level
uint find_sublevel(const Var v) const; // find the sublevel (i.e. trail[X]) of a given variable
//helper functions
bool at_first_init() const;
bool should_init() const;
bool should_check_gauss(const uint decisionlevel, const uint starts) const;
void disable_if_necessary();
void reset_stats();
void update_last_one_in_col(matrixset& m);
private:
//debug functions
bool check_no_conflict(matrixset& m) const; // Are there any conflicts that the matrixset 'm' causes?
const bool nothing_to_propagate(matrixset& m) const; // Are there any conflicts of propagations that matrixset 'm' clauses?
template<class T>
void print_matrix_row(const T& row) const; // Print matrix row 'row'
template<class T>
void print_matrix_row_with_assigns(const T& row) const;
void check_matrix_against_varset(PackedMatrix& matrix,const matrixset& m) const;
const bool check_last_one_in_cols(matrixset& m) const;
const void check_first_one_in_row(matrixset& m, const uint j);
void print_matrix(matrixset& m) const;
void print_last_one_in_cols(matrixset& m) const;
static const string lbool_to_string(const lbool toprint);
};
inline bool Gaussian::should_init() const
{
return (config.decision_until > 0);
}
inline bool Gaussian::should_check_gauss(const uint decisionlevel, const uint starts) const
{
return (!disabled
&& decisionlevel < config.decision_until);
}
inline void Gaussian::canceling(const uint sublevel)
{
if (disabled)
return;
uint a = 0;
for (int i = clauses_toclear.size()-1; i >= 0 && clauses_toclear[i].second > sublevel; i--) {
clauseFree(clauses_toclear[i].first);
a++;
}
clauses_toclear.resize(clauses_toclear.size()-a);
if (messed_matrix_vars_since_reversal)
return;
int c = std::min((int)gauss_last_level, (int)(solver.trail.size())-1);
for (; c >= (int)sublevel; c--) {
Var var = solver.trail[c].var();
if (var < var_is_in.getSize()
&& var_is_in[var]
&& cur_matrixset.var_is_set[var]) {
messed_matrix_vars_since_reversal = true;
return;
}
}
}
inline const uint32_t Gaussian::get_unit_truths() const
{
return unit_truths;
}
inline const uint Gaussian::get_called() const
{
return called;
}
inline const uint Gaussian::get_useful_prop() const
{
return useful_prop;
}
inline const uint Gaussian::get_useful_confl() const
{
return useful_confl;
}
inline const bool Gaussian::get_disabled() const
{
return disabled;
}
inline void Gaussian::set_disabled(const bool toset)
{
disabled = toset;
}
std::ostream& operator << (std::ostream& os, const vec<Lit>& v);
#endif //GAUSSIAN_H

View File

@ -0,0 +1,56 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef GAUSSIANCONFIG_H
#define GAUSSIANCONFIG_H
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "PackedRow.h"
class GaussianConfig
{
public:
GaussianConfig() :
only_nth_gauss_save(2)
, decision_until(0)
, dontDisable(false)
, noMatrixFind(false)
, orderCols(true)
, iterativeReduce(true)
, maxMatrixRows(1000)
, minMatrixRows(20)
{
}
//tuneable gauss parameters
uint only_nth_gauss_save; //save only every n-th gauss matrix
uint decision_until; //do Gauss until this level
bool dontDisable; //If activated, gauss elimination is never disabled
bool noMatrixFind; //Put all xor-s into one matrix, don't find matrixes
bool orderCols; //Order columns according to activity
bool iterativeReduce; //Don't minimise matrix work
uint32_t maxMatrixRows; //The maximum matrix size -- no. of rows
uint32_t minMatrixRows; //The minimum matrix size -- no. of rows
};
#endif //GAUSSIANCONFIG_H

View File

@ -0,0 +1,907 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#include <time.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <limits>
using std::cout;
using std::endl;
using std::ofstream;
#include "Logger.h"
#include "SolverTypes.h"
#include "Solver.h"
#ifdef USE_GAUSS
#include "Gaussian.h"
#endif //USE_GAUSS
#define FST_WIDTH 10
#define SND_WIDTH 35
#define TRD_WIDTH 10
Logger::Logger(int& _verbosity) :
proof_graph_on(false)
, mini_proof(false)
, statistics_on(false)
, max_print_lines(20)
, uniqueid(1)
, proof(NULL)
, sum_conflict_depths(0)
, no_conflicts(0)
, no_decisions(0)
, no_propagations(0)
, sum_decisions_on_branches(0)
, sum_propagations_on_branches(0)
, verbosity(_verbosity)
, begin_called(false)
, proofStarts(0)
{
runid /= 10;
runid = time(NULL) % 10000;
if (verbosity >= 1) printf("c RunID is: #%d\n",runid);
}
void Logger::setSolver(const Solver* _s)
{
S = _s;
}
// Adds a new variable to the knowledge of the logger
void Logger::new_var(const Var var)
{
if (!statistics_on && !proof_graph_on)
return;
if (varnames.size() <= var) {
varnames.resize(var+1, "Noname");
times_var_propagated.resize(var+1, 0);
times_var_guessed.resize(var+1, 0);
depths_of_assigns_for_var.resize(var+1);
depths_of_assigns_unit.resize(var+1, false);
}
}
// Resizes the groupnames and other, related vectors to accomodate for a new group
void Logger::new_group(const uint group)
{
if (groupnames.size() <= group) {
groupnames.resize(group+1, "Noname");
times_group_caused_conflict.resize(group+1, 0);
times_group_caused_propagation.resize(group+1, 0);
depths_of_propagations_for_group.resize(group+1);
depths_of_propagations_unit.resize(group+1, false);
depths_of_conflicts_for_group.resize(group+1);
}
}
string Logger::cut_name_to_size(const string& name) const
{
string ret = name;
uint len = name.length();
while(len > 0 && (name[len-1] == ' ' || name[len-1] == 0x0A || name[len-1] == 0x0D)) {
ret.resize(len-1);
len--;
}
if (len > SND_WIDTH-3) {
ret[SND_WIDTH-3] = '\0';
ret[SND_WIDTH-4] = '.';
ret[SND_WIDTH-5] = '.';
}
return ret;
}
// Adds the new clause group's name to the information stored
void Logger::set_group_name(const uint group, const char* name_tmp)
{
if (!statistics_on && !proof_graph_on)
return;
string name;
if (name_tmp == NULL) return;
else name = name_tmp;
set_group_name(group, name);
}
void Logger::set_group_name(const uint group, string& name)
{
new_group(group);
if (name == "Noname") return;
if (groupnames[group] == "Noname") {
groupnames[group] = name;
} else if (groupnames[group] != name) {
std::cout << "Error! Group no. " << group << "has been named twice. First, as '" << groupnames[group] << "', then second as '" << name << "'. Name the same group the same always, or don't give a name to the second iteration of the same group (i.e just write 'c g groupnumber' on the line" << std::endl;
exit(-1);
}
}
string Logger::get_group_name(const uint group) const
{
assert(group < groupnames.size());
return groupnames[group];
}
string Logger::get_var_name(const Var var) const
{
if (var >= varnames.size()) return "unknown";
return varnames[var];
}
// sets the variable's name
void Logger::set_variable_name(const uint var, char* name_tmp)
{
if (!statistics_on && !proof_graph_on)
return;
new_var(var);
string name;
if (name_tmp == NULL)
name = "";
else
name = name_tmp;
if (varnames[var] == "Noname") {
varnames[var] = name;
} else if (varnames[var] != name) {
printf("Error! Variable no. %d has been named twice. First, as '%s', then second as '%s'. Name the same group the same always, or don't give a name to the second iteration of the same group (i.e just write 'c g groupnumber' on the line\n", var+1, varnames[var].c_str(), name.c_str());
exit(-1);
}
}
void Logger::first_begin()
{
if (begin_called)
return;
begin();
}
void Logger::begin()
{
begin_called = true;
if (proof_graph_on) {
std::stringstream filename;
filename << "proofs/" << runid << "-proof" << proofStarts++ << "-" << S->starts << ".dot";
if (S->starts == 0)
history.push_back(uniqueid);
else {
if (mini_proof)
history.resize(S->decisionLevel()+1);
else
history.resize(S->trail.size()+1);
}
proof = fopen(filename.str().c_str(),"w");
if (!proof) printf("Couldn't open proof file '%s' for writing\n", filename.str().c_str()), exit(-1);
fprintf(proof, "digraph G {\n");
fprintf(proof,"node%d [shape=circle, label=\"BEGIN\", root];\n", history[history.size()-1]);
}
if (statistics_on)
reset_statistics();
}
// For noting conflicts. Updates the proof graph and the statistics.
template<class T>
void Logger::conflict(const confl_type type, const uint goback_level, const uint group, const T& learnt_clause)
{
first_begin();
assert(!(proof == NULL && proof_graph_on));
const uint goback_sublevel = S->trail_lim[goback_level];
if (proof_graph_on) {
uniqueid++;
fprintf(proof,"node%d [shape=polygon,sides=5,label=\"",uniqueid);
if (!mini_proof) {
for (uint32_t i = 0; i != learnt_clause.size(); i++) {
if (learnt_clause[i].sign()) fprintf(proof,"-");
int myvar = learnt_clause[i].var();
if (varnames[myvar] != "Noname")
fprintf(proof,"%s\\n",varnames[myvar].c_str());
else
fprintf(proof,"Var: %d\\n",myvar);
}
}
fprintf(proof,"\"];\n");
fprintf(proof,"node%d -> node%d [label=\"",history[history.size()-1],uniqueid);
if (type == gauss_confl_type)
fprintf(proof,"Gauss\",style=bold");
else
fprintf(proof,"%s\"", groupnames[group].c_str());
fprintf(proof,"];\n");
if (!mini_proof)
history.resize(goback_sublevel+1);
else
history.resize(goback_level+1);
fprintf(proof,"node%d -> node%d [style=dotted];\n",uniqueid,history[history.size()-1]);
}
if (statistics_on) {
times_group_caused_conflict[group]++;
depths_of_conflicts_for_group[group].sum += S->decisionLevel();
depths_of_conflicts_for_group[group].num ++;
no_conflicts++;
sum_conflict_depths += S->trail.size() - S->trail_lim[0];
sum_decisions_on_branches += S->decisionLevel();
sum_propagations_on_branches += S->trail.size() - S->trail_lim[0] - S->decisionLevel();
if (branch_depth_distrib.size() <= S->decisionLevel())
branch_depth_distrib.resize(S->decisionLevel()+1, 0);
branch_depth_distrib[S->decisionLevel()]++;
}
}
template void Logger::conflict(const confl_type type, const uint goback_level, const uint group, const Clause& learnt_clause);
template void Logger::conflict(const confl_type type, const uint goback_level, const uint group, const vec<Lit>& learnt_clause);
// Propagating a literal. Type of literal and the (learned clause's)/(propagating clause's)/(etc) group must be given. Updates the proof graph and the statistics. note: the meaning of the variable 'group' depends on the type
void Logger::propagation(const Lit lit, Clause* c)
{
first_begin();
assert(!(proof == NULL && proof_graph_on));
uint group;
prop_type type;
if (c == NULL) {
if (S->decisionLevel() == 0)
type = add_clause_type;
else
type = guess_type;
group = std::numeric_limits<uint>::max();
} else {
type = simple_propagation_type;
group = c->getGroup();
}
//graph
if (proof_graph_on && (!mini_proof || type == guess_type)) {
uniqueid++;
fprintf(proof,"node%d [shape=box, label=\"",uniqueid);;
if (lit.sign())
fprintf(proof,"-");
if (varnames[lit.var()] != "Noname")
fprintf(proof,"%s\"];\n",varnames[lit.var()].c_str());
else
fprintf(proof,"Var: %d\"];\n",lit.var());
fprintf(proof,"node%d -> node%d [label=\"",history[history.size()-1],uniqueid);
switch (type) {
case simple_propagation_type:
fprintf(proof,"%s\"];\n", groupnames[group].c_str());
break;
case add_clause_type:
fprintf(proof,"red. from clause\"];\n");
break;
case guess_type:
fprintf(proof,"guess\",style=bold];\n");
break;
}
history.push_back(uniqueid);
}
if (statistics_on) {
switch (type) {
case simple_propagation_type:
depths_of_propagations_for_group[group].sum += S->decisionLevel();
depths_of_propagations_for_group[group].num ++;
if (S->decisionLevel() == 0) depths_of_propagations_unit[group] = true;
times_group_caused_propagation[group]++;
case add_clause_type:
no_propagations++;
times_var_propagated[lit.var()]++;
depths_of_assigns_for_var[lit.var()].sum += S->decisionLevel();
depths_of_assigns_for_var[lit.var()].num ++;
if (S->decisionLevel() == 0) depths_of_assigns_unit[lit.var()] = true;
break;
case guess_type:
no_decisions++;
times_var_guessed[lit.var()]++;
depths_of_assigns_for_var[lit.var()].sum += S->decisionLevel();
depths_of_assigns_for_var[lit.var()].num ++;
break;
}
}
}
// Ending of a restart iteration
void Logger::end(const finish_type finish)
{
first_begin();
assert(!(proof == NULL && proof_graph_on));
if (proof_graph_on) {
uniqueid++;
switch (finish) {
case model_found:
fprintf(proof,"node%d [shape=doublecircle, label=\"MODEL\"];\n",uniqueid);
break;
case unsat_model_found:
fprintf(proof,"node%d [shape=doublecircle, label=\"UNSAT\"];\n",uniqueid);
break;
case restarting:
fprintf(proof,"node%d [shape=doublecircle, label=\"Re-starting\\nsearch\"];\n",uniqueid);
break;
}
fprintf(proof,"node%d -> node%d;\n",history[history.size()-1],uniqueid);
fprintf(proof,"}\n");
history.push_back(uniqueid);
proof = (FILE*)fclose(proof);
assert(proof == NULL);
}
if (statistics_on) {
printstats();
if (finish == restarting)
reset_statistics();
}
if (model_found || unsat_model_found)
begin_called = false;
}
void Logger::print_footer() const
{
cout << "+" << std::setfill('-') << std::setw(FST_WIDTH+SND_WIDTH+TRD_WIDTH+4) << "-" << std::setfill(' ') << "+" << endl;
}
void Logger::print_assign_var_order() const
{
vector<pair<double, uint> > prop_ordered;
for (uint i = 0; i < depths_of_assigns_for_var.size(); i++) {
double avg = (double)depths_of_assigns_for_var[i].sum
/(double)depths_of_assigns_for_var[i].num;
if (depths_of_assigns_for_var[i].num > 0 && !depths_of_assigns_unit[i])
prop_ordered.push_back(std::make_pair(avg, i));
}
if (!prop_ordered.empty()) {
print_footer();
print_simple_line(" Variables are assigned in the following order");
print_simple_line(" (unitary clauses not shown)");
print_header("var", "var name", "avg order");
std::sort(prop_ordered.begin(), prop_ordered.end());
print_vars(prop_ordered);
}
}
void Logger::print_prop_order() const
{
vector<pair<double, uint> > prop_ordered;
for (uint i = 0; i < depths_of_propagations_for_group.size(); i++) {
double avg = (double)depths_of_propagations_for_group[i].sum
/(double)depths_of_propagations_for_group[i].num;
if (depths_of_propagations_for_group[i].num > 0 && !depths_of_propagations_unit[i])
prop_ordered.push_back(std::make_pair(avg, i));
}
if (!prop_ordered.empty()) {
print_footer();
print_simple_line(" Propagation depth order of clause groups");
print_simple_line(" (unitary clauses not shown)");
print_header("group", "group name", "avg order");
std::sort(prop_ordered.begin(), prop_ordered.end());
print_groups(prop_ordered);
}
}
void Logger::print_confl_order() const
{
vector<pair<double, uint> > confl_ordered;
for (uint i = 0; i < depths_of_conflicts_for_group.size(); i++) {
double avg = (double)depths_of_conflicts_for_group[i].sum
/(double)depths_of_conflicts_for_group[i].num;
if (depths_of_conflicts_for_group[i].num > 0)
confl_ordered.push_back(std::make_pair(avg, i));
}
if (!confl_ordered.empty()) {
print_footer();
print_simple_line(" Avg. conflict depth order of clause groups");
print_header("groupno", "group name", "avg. depth");
std::sort(confl_ordered.begin(), confl_ordered.end());
print_groups(confl_ordered);
}
}
void Logger::print_times_var_guessed() const
{
vector<pair<uint, uint> > times_var_ordered;
for (uint32_t i = 0; i != varnames.size(); i++) if (times_var_guessed[i] > 0)
times_var_ordered.push_back(std::make_pair(times_var_guessed[i], i));
if (!times_var_ordered.empty()) {
print_footer();
print_simple_line(" No. times variable branched on");
print_header("var", "var name", "no. times");
std::sort(times_var_ordered.rbegin(), times_var_ordered.rend());
print_vars(times_var_ordered);
}
}
void Logger::print_times_group_caused_propagation() const
{
vector<pair<uint, uint> > props_group_ordered;
for (uint i = 0; i < times_group_caused_propagation.size(); i++)
if (times_group_caused_propagation[i] > 0)
props_group_ordered.push_back(std::make_pair(times_group_caused_propagation[i], i));
if (!props_group_ordered.empty()) {
print_footer();
print_simple_line(" No. propagations made by clause groups");
print_header("group", "group name", "no. props");
std::sort(props_group_ordered.rbegin(),props_group_ordered.rend());
print_groups(props_group_ordered);
}
}
void Logger::print_times_group_caused_conflict() const
{
vector<pair<uint, uint> > confls_group_ordered;
for (uint i = 0; i < times_group_caused_conflict.size(); i++)
if (times_group_caused_conflict[i] > 0)
confls_group_ordered.push_back(std::make_pair(times_group_caused_conflict[i], i));
if (!confls_group_ordered.empty()) {
print_footer();
print_simple_line(" No. conflicts made by clause groups");
print_header("group", "group name", "no. confl");
std::sort(confls_group_ordered.rbegin(), confls_group_ordered.rend());
print_groups(confls_group_ordered);
}
}
template<class T>
void Logger::print_line(const uint& number, const string& name, const T& value) const
{
cout << "|" << std::setw(FST_WIDTH) << number << " " << std::setw(SND_WIDTH) << name << " " << std::setw(TRD_WIDTH) << value << "|" << endl;
}
void Logger::print_header(const string& first, const string& second, const string& third) const
{
cout << "|" << std::setw(FST_WIDTH) << first << " " << std::setw(SND_WIDTH) << second << " " << std::setw(TRD_WIDTH) << third << "|" << endl;
print_footer();
}
void Logger::print_groups(const vector<pair<double, uint> >& to_print) const
{
uint i = 0;
typedef vector<pair<double, uint> >::const_iterator myiterator;
for (myiterator it = to_print.begin(); it != to_print.end() && i < max_print_lines; it++, i++) {
print_line(it->second+1, cut_name_to_size(groupnames[it->second]), it->first);
}
print_footer();
}
void Logger::print_groups(const vector<pair<uint, uint> >& to_print) const
{
uint i = 0;
typedef vector<pair<uint, uint> >::const_iterator myiterator;
for (myiterator it = to_print.begin(); it != to_print.end() && i < max_print_lines; it++, i++) {
print_line(it->second+1, cut_name_to_size(groupnames[it->second]), it->first);
}
print_footer();
}
void Logger::print_vars(const vector<pair<double, uint> >& to_print) const
{
uint i = 0;
for (vector<pair<double, uint> >::const_iterator it = to_print.begin(); it != to_print.end() && i < max_print_lines; it++, i++)
print_line(it->second+1, cut_name_to_size(varnames[it->second]), it->first);
print_footer();
}
void Logger::print_vars(const vector<pair<uint, uint> >& to_print) const
{
uint i = 0;
for (vector<pair<uint, uint> >::const_iterator it = to_print.begin(); it != to_print.end() && i < max_print_lines; it++, i++) {
print_line(it->second+1, cut_name_to_size(varnames[it->second]), it->first);
}
print_footer();
}
template<class T>
void Logger::print_line(const string& str, const T& num) const
{
cout << "|" << std::setw(FST_WIDTH+SND_WIDTH+4) << str << std::setw(TRD_WIDTH) << num << "|" << endl;
}
void Logger::print_simple_line(const string& str) const
{
cout << "|" << std::setw(FST_WIDTH+SND_WIDTH+TRD_WIDTH+4) << str << "|" << endl;
}
void Logger::print_center_line(const string& str) const
{
uint middle = (FST_WIDTH+SND_WIDTH+TRD_WIDTH+4-str.size())/2;
int rest = FST_WIDTH+SND_WIDTH+TRD_WIDTH+4-middle*2-str.size();
cout << "|" << std::setw(middle) << " " << str << std::setw(middle + rest) << " " << "|" << endl;
}
void Logger::print_branch_depth_distrib() const
{
//cout << "--- Branch depth stats ---" << endl;
const uint range = 20;
map<uint, uint> range_stat;
uint i = 0;
for (vector<uint>::const_iterator it = branch_depth_distrib.begin(); it != branch_depth_distrib.end(); it++, i++) {
range_stat[i/range] += *it;
}
print_footer();
print_simple_line(" No. search branches with branch depth between");
print_line("Branch depth between", "no. br.-s");
print_footer();
std::stringstream ss;
ss << "branch_depths/branch_depth_file" << runid << "-" << S->starts << ".txt";
ofstream branch_depth_file;
branch_depth_file.open(ss.str().c_str());
i = 0;
for (map<uint, uint>::iterator it = range_stat.begin(); it != range_stat.end(); it++, i++) {
std::stringstream ss2;
ss2 << it->first*range << " - " << it->first*range + range-1;
print_line(ss2.str(), it->second);
if (branch_depth_file.is_open()) {
branch_depth_file << i << "\t" << it->second << "\t";
if (i % 5 == 0)
branch_depth_file << "\"" << it->first*range << "\"";
else
branch_depth_file << "\"\"";
branch_depth_file << endl;
}
}
if (branch_depth_file.is_open())
branch_depth_file.close();
print_footer();
}
void Logger::print_learnt_clause_distrib() const
{
map<uint, uint> learnt_sizes;
const vec<Clause*>& learnts = S->get_learnts();
uint maximum = 0;
for (uint i = 0; i < learnts.size(); i++)
{
uint size = learnts[i]->size();
maximum = std::max(maximum, size);
map<uint, uint>::iterator it = learnt_sizes.find(size);
if (it == learnt_sizes.end())
learnt_sizes[size] = 1;
else
it->second++;
}
learnt_sizes[0] = S->get_unitary_learnts_num();
uint slice = (maximum+1)/max_print_lines + (bool)((maximum+1)%max_print_lines);
print_footer();
print_simple_line(" Learnt clause length distribution");
print_line("Length between", "no. cl.");
print_footer();
uint until = slice;
uint from = 0;
while(until < maximum+1) {
std::stringstream ss2;
ss2 << from << " - " << until-1;
uint sum = 0;
for (; from < until; from++) {
map<uint, uint>::const_iterator it = learnt_sizes.find(from);
if (it != learnt_sizes.end())
sum += it->second;
}
print_line(ss2.str(), sum);
until += slice;
}
print_footer();
print_leearnt_clause_graph_distrib(maximum, learnt_sizes);
}
void Logger::print_leearnt_clause_graph_distrib(const uint maximum, const map<uint, uint>& learnt_sizes) const
{
uint no_slices = FST_WIDTH + SND_WIDTH + TRD_WIDTH + 4-3;
uint slice = (maximum+1)/no_slices + (bool)((maximum+1)%no_slices);
uint until = slice;
uint from = 0;
vector<uint> slices;
uint hmax = 0;
while(until < maximum+1) {
uint sum = 0;
for (; from < until; from++) {
map<uint, uint>::const_iterator it = learnt_sizes.find(from);
if (it != learnt_sizes.end())
sum += it->second;
}
slices.push_back(sum);
until += slice;
hmax = std::max(hmax, sum);
}
slices.resize(no_slices, 0);
uint height = max_print_lines;
uint hslice = (hmax+1)/height + (bool)((hmax+1)%height);
if (hslice == 0) return;
print_simple_line(" Learnt clause distribution in graph form");
print_footer();
string yaxis = "Number";
uint middle = (height-yaxis.size())/2;
for (int i = height-1; i > 0; i--) {
cout << "| ";
if (height-1-i >= middle && height-1-i-middle < yaxis.size())
cout << yaxis[height-1-i-middle] << " ";
else
cout << " ";
for (uint i2 = 0; i2 != no_slices; i2++) {
if (slices[i2]/hslice >= (uint)i) cout << "+";
else cout << " ";
}
cout << "|" << endl;
}
print_center_line(" Learnt clause size");
print_footer();
}
void Logger::print_general_stats() const
{
print_footer();
print_simple_line(" Standard MiniSat stats -- for all restarts until now");
print_footer();
print_line("Restart number", S->starts);
print_line("Number of conflicts", S->conflicts);
print_line("Number of decisions", S->decisions);
print_line("Number of variables", S->order_heap.size());
print_line("Number of clauses", S->nClauses());
print_line("Number of literals in clauses",S->clauses_literals);
print_line("Avg. literals per learnt clause",(double)S->learnts_literals/(double)S->nLearnts());
print_line("Progress estimate (%):", S->progress_estimate*100.0);
print_line("All unitary learnts until now", S->get_unitary_learnts_num());
print_footer();
}
void Logger::print_learnt_unitaries(const uint from, const string display) const
{
print_footer();
print_simple_line(display);
print_header("var", "name", "value");
uint32_t until;
if (S->decisionLevel() > 0)
until = S->trail_lim[0];
else
until = S->trail.size();
for (uint i = from; i < until; i++) {
Var var = S->trail[i].var();
bool value = !(S->trail[i].sign());
print_line(var+1, cut_name_to_size(varnames[var]), value);
}
print_footer();
}
// Prints statistics on the console
void Logger::printstats() const
{
assert(statistics_on);
assert(varnames.size() == times_var_guessed.size());
assert(varnames.size() == times_var_propagated.size());
const uint fullwidth = FST_WIDTH+SND_WIDTH+TRD_WIDTH+4;
cout << endl;
cout << "+" << std::setfill('=') << std::setw(fullwidth) << "=" << "+" << endl;
std::stringstream tmp;
tmp << " STATS FOR RESTART NO. " << std::setw(3) << S->starts << " BEGIN ";
uint len = (fullwidth-2)/2-tmp.str().length()/2;
uint len2 = len + tmp.str().length()%2 + (fullwidth-2)%2;
cout << "||" << std::setfill('*') << std::setw(len) << "*" << tmp.str() << std::setw(len2) << "*" << "||" << endl;
cout << "+" << std::setfill('=') << std::setw(fullwidth) << "=" << std::setfill(' ') << "+" << endl;
cout.setf(std::ios_base::left);
cout.precision(2);
print_statistics_note();
print_times_var_guessed();
print_times_group_caused_propagation();
print_times_group_caused_conflict();
print_prop_order();
print_confl_order();
print_assign_var_order();
print_branch_depth_distrib();
print_learnt_clause_distrib();
#ifdef USE_GAUSS
print_matrix_stats();
#endif //USE_GAUSS
print_learnt_unitaries(0," Unitary clauses learnt until now");
print_learnt_unitaries(last_unitary_learnt_clauses, " Unitary clauses during this restart");
print_advanced_stats();
print_general_stats();
}
#ifdef USE_GAUSS
void Logger::print_matrix_stats() const
{
print_footer();
print_simple_line(" Matrix statistics");
print_footer();
uint i = 0;
for (vector<Gaussian*>::const_iterator it = S->gauss_matrixes.begin(), end = S->gauss_matrixes.end(); it != end; it++, i++) {
std::stringstream s;
s << "Matrix " << i << " enabled";
std::stringstream tmp;
tmp << std::boolalpha << !(*it)->get_disabled();
print_line(s.str(), tmp.str());
s.str("");
s << "Matrix " << i << " called";
print_line(s.str(), (*it)->get_called());
s.str("");
s << "Matrix " << i << " propagations";
print_line(s.str(), (*it)->get_useful_prop());
s.str("");
s << "Matrix " << i << " conflicts";
print_line(s.str(), (*it)->get_useful_confl());
}
print_footer();
}
#endif //USE_GAUSS
void Logger::print_advanced_stats() const
{
print_footer();
print_simple_line(" Advanced statistics - for only this restart");
print_footer();
print_line("Unitary learnts", S->get_unitary_learnts_num() - last_unitary_learnt_clauses);
print_line("No. branches visited", no_conflicts);
print_line("Avg. branch depth", (double)sum_conflict_depths/(double)no_conflicts);
print_line("No. decisions", no_decisions);
print_line("No. propagations",no_propagations);
//printf("no progatations/no decisions (i.e. one decision gives how many propagations on average *for the whole search graph*): %f\n", (double)no_propagations/(double)no_decisions);
//printf("no propagations/sum decisions on branches (if you look at one specific branch, what is the average number of propagations you will find?): %f\n", (double)no_propagations/(double)sum_decisions_on_branches);
print_simple_line("sum decisions on branches/no. branches");
print_simple_line(" (in a given branch, what is the avg.");
print_line(" no. of decisions?)",(double)sum_decisions_on_branches/(double)no_conflicts);
print_simple_line("sum propagations on branches/no. branches");
print_simple_line(" (in a given branch, what is the");
print_line(" avg. no. of propagations?)",(double)sum_propagations_on_branches/(double)no_conflicts);
print_footer();
}
void Logger::print_statistics_note() const
{
print_footer();
print_simple_line("Statistics note: If you used CryptoMiniSat as");
print_simple_line("a library then vars are all shifted by 1 here");
print_simple_line("and in every printed output of the solver.");
print_simple_line("This does not apply when you use CryptoMiniSat");
print_simple_line("as a stand-alone program.");
print_footer();
}
// resets all stored statistics. Might be useful, to generate statistics for each restart and not for the whole search in general
void Logger::reset_statistics()
{
assert(S->decisionLevel() == 0);
assert(times_var_guessed.size() == times_var_propagated.size());
assert(times_group_caused_conflict.size() == times_group_caused_propagation.size());
typedef vector<uint>::iterator vecit;
for (vecit it = times_var_guessed.begin(); it != times_var_guessed.end(); it++)
*it = 0;
for (vecit it = times_var_propagated.begin(); it != times_var_propagated.end(); it++)
*it = 0;
for (vecit it = times_group_caused_conflict.begin(); it != times_group_caused_conflict.end(); it++)
*it = 0;
for (vecit it = times_group_caused_propagation.begin(); it != times_group_caused_propagation.end(); it++)
*it = 0;
for (vecit it = confls_by_group.begin(); it != confls_by_group.end(); it++)
*it = 0;
for (vecit it = props_by_group.begin(); it != props_by_group.end(); it++)
*it = 0;
typedef vector<MyAvg>::iterator avgIt;
for (avgIt it = depths_of_propagations_for_group.begin(); it != depths_of_propagations_for_group.end(); it++) {
it->sum = 0;
it->num = 0;
}
for (avgIt it = depths_of_conflicts_for_group.begin(); it != depths_of_conflicts_for_group.end(); it++) {
it->sum = 0;
it->num = 0;
}
for (avgIt it = depths_of_assigns_for_var.begin(); it != depths_of_assigns_for_var.end(); it++) {
it->sum = 0;
it->num = 0;
}
for (uint i = 0; i < depths_of_assigns_unit.size(); i++)
depths_of_assigns_unit[i] = false;
for (uint i = 0; i < depths_of_propagations_unit.size(); i++)
depths_of_propagations_unit[i] = false;
sum_conflict_depths = 0;
no_conflicts = 0;
no_decisions = 0;
no_propagations = 0;
sum_decisions_on_branches = 0;
sum_propagations_on_branches = 0;
branch_depth_distrib.clear();
last_unitary_learnt_clauses = S->get_unitary_learnts_num();
}

View File

@ -0,0 +1,184 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#ifndef LOGGER_H
#define LOGGER_H
#include <stdio.h>
#include <set>
#include <vector>
#include <string>
#include <map>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "Vec.h"
#include "Heap.h"
#include "Alg.h"
#include "SolverTypes.h"
#include "limits.h"
#include "Clause.h"
using std::vector;
using std::pair;
using std::string;
using std::map;
class Solver;
class MyAvg {
public:
MyAvg() :
sum(0)
, num(0)
{}
uint sum;
uint num;
};
class Logger
{
public:
Logger(int& vebosity);
void setSolver(const Solver* S);
//types of props, confl, and finish
enum prop_type { add_clause_type, guess_type, simple_propagation_type};
enum confl_type { simple_confl_type, gauss_confl_type };
enum finish_type { model_found, unsat_model_found, restarting};
//Conflict and propagation(guess is also a proapgation...)
template<class T>
void conflict(const confl_type type, const uint goback_level, const uint group, const T& learnt_clause);
void propagation(const Lit lit, Clause* c);
//functions to add/name variables
void new_var(const Var var);
void set_variable_name(const uint var, char* name_tmp);
//function to name clause groups
void set_group_name(const uint group, const char* name_tmp);
void set_group_name(const uint group, string& name);
string get_group_name(const uint group) const;
string get_var_name(const Var var) const;
void begin();
void end(const finish_type finish);
void newclause(const vec<Lit>& ps, const bool xor_clause, const uint group);
bool proof_graph_on;
bool mini_proof;
bool statistics_on;
private:
void new_group(const uint group);
string cut_name_to_size(const string& name) const;
void print_groups(const vector<pair<uint, uint> >& to_print) const;
void print_groups(const vector<pair<double, uint> >& to_print) const;
void print_vars(const vector<pair<uint, uint> >& to_print) const;
void print_vars(const vector<pair<double, uint> >& to_print) const;
void print_times_var_guessed() const;
void print_times_group_caused_propagation() const;
void print_times_group_caused_conflict() const;
void print_branch_depth_distrib() const;
void print_learnt_clause_distrib() const;
void print_leearnt_clause_graph_distrib(const uint maximum, const map<uint, uint>& learnt_sizes) const;
void print_advanced_stats() const;
void print_statistics_note() const;
void print_matrix_stats() const;
void print_general_stats() const;
void print_learnt_unitaries(const uint from, const string display) const;
uint max_print_lines;
template<class T>
void print_line(const uint& number, const string& name, const T& value) const;
void print_header(const string& first, const string& second, const string& third) const;
void print_footer() const;
template<class T>
void print_line(const string& str, const T& num) const;
void print_simple_line(const string& str) const;
void print_center_line(const string& str) const;
void print_confl_order() const;
void print_prop_order() const;
void print_assign_var_order() const;
void printstats() const;
void reset_statistics();
//internal data structures
uint uniqueid; //used to store the last unique ID given to a node
vector<uint> history; //stores the node uniqueIDs
//graph drawing
FILE* proof; //The file to store the proof
uint runid;
//---------------------
//statistics collection
//---------------------
//group and var names
vector<string> groupnames;
vector<string> varnames;
//confls and props grouped by clause groups
vector<uint> confls_by_group;
vector<uint> props_by_group;
//props and guesses grouped by vars
vector<uint> times_var_guessed;
vector<uint> times_var_propagated;
vector<uint> times_group_caused_conflict;
vector<uint> times_group_caused_propagation;
vector<MyAvg> depths_of_propagations_for_group;
vector<bool> depths_of_propagations_unit;
vector<MyAvg> depths_of_conflicts_for_group;
vector<MyAvg> depths_of_assigns_for_var;
vector<bool> depths_of_assigns_unit;
//the distribution of branch depths. first = depth, second = number of occurances
vector<uint> branch_depth_distrib;
uint64_t sum_conflict_depths;
uint64_t no_conflicts;
uint64_t no_decisions;
uint64_t no_propagations;
uint64_t sum_decisions_on_branches;
uint64_t sum_propagations_on_branches;
uint64_t last_unitary_learnt_clauses;
//message display properties
const int& verbosity;
const Solver* S;
void first_begin();
bool begin_called;
uint proofStarts;
};
#endif //LOGGER_H

878
packages/bee/cryptominisat-2.5.1/Solver/Main.C vendored Executable file
View File

@ -0,0 +1,878 @@
/******************************************************************************************[Main.C]
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#include <ctime>
#include <cstring>
#include <errno.h>
#include <string.h>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include <signal.h>
#ifndef DISABLE_ZLIB
#include <zlib.h>
#endif // DISABLE_ZLIB
#include "Logger.h"
#include "Solver.h"
#include "time_mem.h"
#include "constants.h"
using std::cout;
using std::endl;
/*************************************************************************************/
#if defined(__linux__)
#include <fpu_control.h>
#endif
static bool grouping = false;
static bool debugLib = false;
static bool debugNewVar = false;
static char learnts_filename[500];
static bool dumpLearnts = false;
static uint32_t maxLearntsSize = std::numeric_limits<uint32_t>::max();
static bool printResult = true;
//=================================================================================================
// DIMACS Parser:
#define CHUNK_LIMIT 1048576
#define MAX_NAMES_SIZE 1000
class StreamBuffer
{
#ifdef DISABLE_ZLIB
FILE * in;
#else
gzFile in;
#endif // DISABLE_ZLIB
char buf[CHUNK_LIMIT];
int pos;
int size;
void assureLookahead() {
if (pos >= size) {
pos = 0;
#ifdef DISABLE_ZLIB
#ifdef VERBOSE_DEBUG
printf("buf = %08X\n", buf);
printf("sizeof(buf) = %u\n", sizeof(buf));
#endif //VERBOSE_DEBUG
size = fread(buf, 1, sizeof(buf), in);
#else
size = gzread(in, buf, sizeof(buf));
#endif // DISABLE_ZLIB
}
}
public:
#ifdef DISABLE_ZLIB
StreamBuffer(FILE * i) : in(i), pos(0), size(0) {
#else
StreamBuffer(gzFile i) : in(i), pos(0), size(0) {
#endif // DISABLE_ZLIB
assureLookahead();
}
int operator * () {
return (pos >= size) ? EOF : buf[pos];
}
void operator ++ () {
pos++;
assureLookahead();
}
};
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template<class B>
static void skipWhitespace(B& in)
{
while ((*in >= 9 && *in <= 13) || *in == 32)
++in;
}
template<class B>
static void skipLine(B& in)
{
for (;;) {
if (*in == EOF || *in == '\0') return;
if (*in == '\n') {
++in;
return;
}
++in;
}
}
template<class B>
static void untilEnd(B& in, char* ret)
{
uint32_t sizeRead = 0;
for (;sizeRead < MAX_NAMES_SIZE-1; sizeRead++) {
if (*in == EOF || *in == '\0') return;
if (*in == '\n') {
return;
}
*ret = *in;
ret++;
*ret = '\0';
++in;
}
}
template<class B>
static int parseInt(B& in)
{
int val = 0;
bool neg = false;
skipWhitespace(in);
if (*in == '-') neg = true, ++in;
else if (*in == '+') ++in;
if (*in < '0' || *in > '9') printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
while (*in >= '0' && *in <= '9')
val = val*10 + (*in - '0'),
++in;
return neg ? -val : val;
}
inline std::string stringify(uint x)
{
std::ostringstream o;
o << x;
return o.str();
}
template<class B>
static void parseString(B& in, std::string& str)
{
str.clear();
skipWhitespace(in);
while (*in != ' ' && *in != '\n') {
str += *in;
++in;
}
}
template<class B>
static void readClause(B& in, Solver& S, vec<Lit>& lits)
{
int parsed_lit;
Var var;
lits.clear();
for (;;) {
parsed_lit = parseInt(in);
if (parsed_lit == 0) break;
var = abs(parsed_lit)-1;
if (!debugNewVar) {
while (var >= S.nVars()) S.newVar();
}
lits.push( (parsed_lit > 0) ? Lit(var, false) : Lit(var, true) );
}
}
template<class B>
static bool match(B& in, const char* str)
{
for (; *str != 0; ++str, ++in)
if (*str != *in)
return false;
return true;
}
template<class B>
static void parse_DIMACS_main(B& in, Solver& S)
{
vec<Lit> lits;
int group = 0;
string str;
uint debugLibPart = 1;
char name[MAX_NAMES_SIZE];
for (;;) {
skipWhitespace(in);
switch (*in) {
case EOF:
return;
case 'p':
if (match(in, "p cnf")) {
int vars = parseInt(in);
int clauses = parseInt(in);
if (S.verbosity >= 1) {
printf("c | Number of variables: %-12d |\n", vars);
printf("c | Number of clauses: %-12d |\n", clauses);
}
} else {
printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
}
break;
case 'c':
++in;
parseString(in, str);
if (str == "v" || str == "var") {
int var = parseInt(in);
skipWhitespace(in);
if (var <= 0) cout << "PARSE ERROR! Var number must be a positive integer" << endl, exit(3);
name[0] = '\0';
untilEnd(in, name);
S.setVariableName(var-1, name);
} else if (debugLib && str == "Solver::solve()") {
lbool ret = S.solve();
std::string s = "debugLibPart" + stringify(debugLibPart) +".output";
FILE* res = fopen(s.c_str(), "w");
if (ret == l_True) {
fprintf(res, "SAT\n");
for (Var i = 0; i != S.nVars(); i++)
if (S.model[i] != l_Undef)
fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1);
fprintf(res, " 0\n");
} else if (ret == l_False) {
fprintf(res, "UNSAT\n");
} else if (ret == l_Undef) {
assert(false);
} else {
assert(false);
}
fclose(res);
debugLibPart++;
} else if (debugNewVar && str == "Solver::newVar()") {
S.newVar();
} else {
//printf("didn't understand in CNF file: 'c %s'\n", str.c_str());
skipLine(in);
}
break;
default:
bool xor_clause = false;
if ( *in == 'x') xor_clause = true, ++in;
readClause(in, S, lits);
skipLine(in);
name[0] = '\0';
if (!grouping) group++;
else {
if (*in != 'c') {
cout << "PARSE ERROR! Group must be present after earch clause ('c' missing after clause line)" << endl;
exit(3);
}
++in;
parseString(in, str);
if (str != "g" && str != "group") {
cout << "PARSE ERROR! Group must be present after each clause('group' missing)!" << endl;
cout << "Instead of 'group' there was:" << str << endl;
exit(3);
}
group = parseInt(in);
if (group <= 0) printf("PARSE ERROR! Group number must be a positive integer\n"), exit(3);
skipWhitespace(in);
untilEnd(in, name);
}
if (xor_clause) {
bool xor_clause_inverted = false;
for (uint32_t i = 0; i < lits.size(); i++) {
xor_clause_inverted ^= lits[i].sign();
}
S.addXorClause(lits, xor_clause_inverted, group, name);
} else
S.addClause(lits, group, name);
break;
}
}
}
// Inserts problem into solver.
//
#ifdef DISABLE_ZLIB
static void parse_DIMACS(FILE * input_stream, Solver& S)
#else
static void parse_DIMACS(gzFile input_stream, Solver& S)
#endif // DISABLE_ZLIB
{
StreamBuffer in(input_stream);
parse_DIMACS_main(in, S);
}
//=================================================================================================
template<class T, class T2>
inline void printStatsLine(string left, T value, T2 value2, string extra)
{
cout << std::fixed << std::left << std::setw(24) << left << ": " << std::setw(11) << std::setprecision(2) << value << " (" << std::left << std::setw(9) << std::setprecision(2) << value2 << " " << extra << ")" << std::endl;
}
template<class T>
inline void printStatsLine(string left, T value, string extra = "")
{
cout << std::fixed << std::left << std::setw(24) << left << ": " << std::setw(11) << std::setprecision(2) << value << extra << std::endl;
}
void printStats(Solver& solver)
{
double cpu_time = cpuTime();
uint64_t mem_used = memUsed();
//Restarts stats
printStatsLine("c restarts", solver.starts);
printStatsLine("c dynamic restarts", solver.dynStarts);
printStatsLine("c static restarts", solver.staticStarts);
printStatsLine("c full restarts", solver.fullStarts);
//Learnts stats
printStatsLine("c learnts DL2", solver.nbDL2);
printStatsLine("c learnts size 2", solver.nbBin);
printStatsLine("c learnts size 1", solver.get_unitary_learnts_num(), (double)solver.get_unitary_learnts_num()/(double)solver.nVars()*100.0, "% of vars");
//Subsumer stats
printStatsLine("c v-elim SatELite", solver.getNumElimSubsume(), (double)solver.getNumElimSubsume()/(double)solver.nVars()*100.0, "% vars");
printStatsLine("c SatELite time", solver.getTotalTimeSubsumer(), solver.getTotalTimeSubsumer()/cpu_time*100.0, "% time");
//XorSubsumer stats
printStatsLine("c v-elim xor", solver.getNumElimXorSubsume(), (double)solver.getNumElimXorSubsume()/(double)solver.nVars()*100.0, "% vars");
printStatsLine("c xor elim time", solver.getTotalTimeXorSubsumer(), solver.getTotalTimeXorSubsumer()/cpu_time*100.0, "% time");
//VarReplacer stats
printStatsLine("c num binary xor trees", solver.getNumXorTrees());
printStatsLine("c binxor trees' crown", solver.getNumXorTreesCrownSize(), (double)solver.getNumXorTreesCrownSize()/(double)solver.getNumXorTrees(), "leafs/tree");
//OTF clause improvement stats
printStatsLine("c OTF clause improved", solver.improvedClauseNo, (double)solver.improvedClauseNo/(double)solver.conflicts, "clauses/conflict");
printStatsLine("c OTF impr. size diff", solver.improvedClauseSize, (double)solver.improvedClauseSize/(double)solver.improvedClauseNo, " lits/clause");
#ifdef USE_GAUSS
if (solver.gaussconfig.decision_until > 0) {
std::cout << "c " << std::endl;
printStatsLine("c gauss unit truths ", solver.get_sum_gauss_unit_truths());
printStatsLine("c gauss called", solver.get_sum_gauss_called());
printStatsLine("c gauss conflicts ", solver.get_sum_gauss_confl(), (double)solver.get_sum_gauss_confl() / (double)solver.get_sum_gauss_called() * 100.0, " %");
printStatsLine("c gauss propagations ", solver.get_sum_gauss_prop(), (double)solver.get_sum_gauss_prop() / (double)solver.get_sum_gauss_called() * 100.0, " %");
printStatsLine("c gauss useful", ((double)solver.get_sum_gauss_prop() + (double)solver.get_sum_gauss_confl())/ (double)solver.get_sum_gauss_called() * 100.0, " %");
std::cout << "c " << std::endl;
}
#endif
//Search stats
printStatsLine("c conflicts", solver.conflicts, (double)solver.conflicts/cpu_time, "/ sec");
printStatsLine("c decisions", solver.decisions, (double)solver.rnd_decisions*100.0/(double)solver.decisions, "% random");
printStatsLine("c propagations", solver.propagations, (double)solver.propagations/cpu_time, "/ sec");
printStatsLine("c conflict literals", solver.tot_literals, (double)(solver.max_literals - solver.tot_literals)*100.0/ (double)solver.max_literals, "% deleted");
//General stats
printStatsLine("c Memory used", (double)mem_used / 1048576.0, " MB");
printStatsLine("c CPU time", cpu_time, " s");
}
Solver* solver;
static void SIGINT_handler(int signum)
{
printf("\n");
printf("*** INTERRUPTED ***\n");
printStats(*solver);
if (dumpLearnts) {
solver->dumpSortedLearnts(learnts_filename, maxLearntsSize);
cout << "c Sorted learnt clauses dumped to file '" << learnts_filename << "'" << endl;
}
printf("\n");
printf("*** INTERRUPTED ***\n");
exit(1);
}
//=================================================================================================
// Main:
void printUsage(char** argv, Solver& S)
{
#ifdef DISABLE_ZLIB
printf("USAGE: %s [options] <input-file> <result-output-file>\n\n where input is plain DIMACS.\n\n", argv[0]);
#else
printf("USAGE: %s [options] <input-file> <result-output-file>\n\n where input may be either in plain or gzipped DIMACS.\n\n", argv[0]);
#endif // DISABLE_ZLIB
printf("OPTIONS:\n\n");
printf(" --polarity-mode = {true,false,rnd,auto} [default: auto]. Selects the default\n");
printf(" polarity mode. Auto is the Jeroslow&Wang method\n");
//printf(" -decay = <num> [ 0 - 1 ]\n");
printf(" --rnd-freq = <num> [ 0 - 1 ]\n");
printf(" --verbosity = {0,1,2}\n");
#ifdef STATS_NEEDED
printf(" --proof-log = Logs the proof into files 'proofN.dot', where N is the\n");
printf(" restart number. The log can then be visualized using\n");
printf(" the 'dot' program from the graphviz package\n");
printf(" --grouping = Lets you group clauses, and customize the groups' names.\n");
printf(" This helps when printing statistics\n");
printf(" --stats = Computes and prints statistics during the search\n");
#endif
printf(" --randomize = <seed> [0 - 2^32-1] Sets random seed, used for picking\n");
printf(" decision variables (default = 0)\n");
printf(" --restrict = <num> [1 - varnum] when picking random variables to branch\n");
printf(" on, pick one that in the 'num' most active vars useful\n");
printf(" for cryptographic problems, where the question is the key,\n");
printf(" which is usually small (e.g. 80 bits)\n");
printf(" --restarts = <num> [1 - 2^32-1] No more than the given number of\n");
printf(" restarts will be performed during search\n");
printf(" --nonormxorfind = Don't find and collect >2-long xor-clauses from\n");
printf(" regular clauses\n");
printf(" --nobinxorfind = Don't find and collect 2-long xor-clauses from\n");
printf(" regular clauses\n");
printf(" --noregbxorfind = Don't regularly find and collect 2-long xor-clauses\n");
printf(" from regular clauses\n");
printf(" --noconglomerate = Don't conglomerate 2 xor clauses when one var is dependent\n");
printf(" --nosimplify = Don't do regular simplification rounds\n");
printf(" --greedyunbound = Greedily unbound variables that are not needed for SAT\n");
printf(" --debuglib = Solve at specific 'c Solver::solve()' points in the CNF\n");
printf(" file. Used to debug file generated by Solver's\n");
printf(" needLibraryCNFFile() function\n");
printf(" --debugnewvar = Add new vars at specific 'c Solver::newVar()' points in \n");
printf(" the CNF file. Used to debug file generated by Solver's\n");
printf(" needLibraryCNFFile() function.\n");
printf(" --novarreplace = Don't perform variable replacement. Needed for programmable\n");
printf(" solver feature\n");
printf(" --restart = {auto, static, dynamic} Which kind of restart strategy to\n");
printf(" follow. Default is auto\n");
printf(" --dumplearnts = <filename> If interrupted or reached restart limit, dump\n");
printf(" the learnt clauses to the specified file. Maximum size of\n");
printf(" dumped clauses can be specified with next option.\n");
printf(" --maxdumplearnts = [0 - 2^32-1] When dumping the learnts to file, what\n");
printf(" should be maximum length of the clause dumped. Useful\n");
printf(" to make the resulting file smaller. Default is 2^32-1\n");
printf(" note: 2-long XOR-s are always dumped.\n");
printf(" --maxsolutions = Search for given amount of solutions\n");
printf(" --nofailedvar = Don't search for failed vars, and don't search for vars\n");
printf(" doubly propagated to the same value\n");
printf(" --noheuleprocess = Don't try to minimise XORs by XOR-ing them together.\n");
printf(" Algo. as per global/local substitution in Heule's thesis\n");
printf(" --nosatelite = Don't do clause subsumption, clause strengthening and\n");
printf(" variable elimination (implies -novarelim and -nosubsume1).\n");
printf(" --noxorsubs = Don't try to subsume xor-clauses.\n");
printf(" --nohyperbinres = Don't carry out hyper-binary resolution\n");
printf(" --nosolprint = Don't print the satisfying assignment if the solution\n");
printf(" is SAT\n");
printf(" --novarelim = Don't perform variable elimination as per Een and Biere\n");
printf(" --nosubsume1 = Don't perform clause contraction through resolution\n");
printf(" --noparthander = Don't find and solve subroblems with subsolvers\n");
#ifdef USE_GAUSS
printf(" --gaussuntil = <num> Depth until which Gaussian elimination is active.\n");
printf(" Giving 0 switches off Gaussian elimination\n");
printf(" --nomatrixfind = Don't find distinct matrixes. Put all xors into one\n");
printf(" big matrix\n");
printf(" --noiterreduce = Don't reduce iteratively the matrix that is updated\n");
printf(" --noordercol = Don't order variables in the columns of Gaussian\n");
printf(" elimination. Effectively disables iterative reduction\n");
printf(" of the matrix\n");
printf(" --maxmatrixrows = [0 - 2^32-1] Set maximum no. of rows for gaussian matrix.\n");
printf(" Too large matrixes should bee discarded for\n");
printf(" reasons of efficiency. Default: %d\n", S.gaussconfig.maxMatrixRows);
printf(" --minmatrixrows = [0 - 2^32-1] Set minimum no. of rows for gaussian matrix.\n");
printf(" Normally, too small matrixes are discarded for\n");
printf(" reasons of efficiency. Default: %d\n", S.gaussconfig.minMatrixRows);
printf(" --savematrix = [0 - 2^32-1] Save matrix every Nth decision level.\n");
printf(" Default: %d\n", S.gaussconfig.only_nth_gauss_save);
#endif //USE_GAUSS
//printf(" --addoldlearnts = Readd old learnts for failed variable searching.\n");
//printf(" These learnts are usually deleted, but may help\n");
printf(" --noextrabins = Don't add binary clauses when doing failed lit probing.\n");
printf(" --noremovebins = Don't remove useless binary clauses\n");
printf(" --noregremovebins= Don't remove useless binary clauses regularly\n");
printf(" --nosubswithbins = Don't subsume with non-existent bins\n");
printf(" --norsubswithbins= Don't subsume regularly with non-existent bins\n");
printf("\n");
}
const char* hasPrefix(const char* str, const char* prefix)
{
int len = strlen(prefix);
if (strncmp(str, prefix, len) == 0)
return str + len;
else
return NULL;
}
int main(int argc, char** argv)
{
Solver S;
S.verbosity = 2;
const char* value;
int j = 0;
unsigned long max_nr_of_solutions = 1;
unsigned long current_nr_of_solutions = 1;
for (int i = 0; i < argc; i++) {
if ((value = hasPrefix(argv[i], "--polarity-mode="))) {
if (strcmp(value, "true") == 0)
S.polarity_mode = Solver::polarity_true;
else if (strcmp(value, "false") == 0)
S.polarity_mode = Solver::polarity_false;
else if (strcmp(value, "rnd") == 0)
S.polarity_mode = Solver::polarity_rnd;
else if (strcmp(value, "auto") == 0)
S.polarity_mode = Solver::polarity_auto;
else {
printf("ERROR! unknown polarity-mode %s\n", value);
exit(0);
}
} else if ((value = hasPrefix(argv[i], "--rnd-freq="))) {
double rnd;
if (sscanf(value, "%lf", &rnd) <= 0 || rnd < 0 || rnd > 1) {
printf("ERROR! illegal rnd-freq constant %s\n", value);
exit(0);
}
S.random_var_freq = rnd;
/*} else if ((value = hasPrefix(argv[i], "--decay="))) {
double decay;
if (sscanf(value, "%lf", &decay) <= 0 || decay <= 0 || decay > 1) {
printf("ERROR! illegal decay constant %s\n", value);
exit(0);
}
S.var_decay = 1 / decay;*/
} else if ((value = hasPrefix(argv[i], "--verbosity="))) {
int verbosity = (int)strtol(value, NULL, 10);
if (verbosity == EINVAL || verbosity == ERANGE) {
printf("ERROR! illegal verbosity level %s\n", value);
exit(0);
}
S.verbosity = verbosity;
#ifdef STATS_NEEDED
} else if ((value = hasPrefix(argv[i], "--grouping"))) {
grouping = true;
} else if ((value = hasPrefix(argv[i], "--proof-log"))) {
S.needProofGraph();
} else if ((value = hasPrefix(argv[i], "--stats"))) {
S.needStats();
#endif //STATS_NEEDED
} else if ((value = hasPrefix(argv[i], "--randomize="))) {
uint32_t seed;
if (sscanf(value, "%d", &seed) < 0) {
printf("ERROR! illegal seed %s\n", value);
exit(0);
}
cout << "c seed:" << seed << endl;
S.setSeed(seed);
} else if ((value = hasPrefix(argv[i], "--restrict="))) {
uint branchTo;
if (sscanf(value, "%d", &branchTo) < 0 || branchTo < 1) {
printf("ERROR! illegal restricted pick branch number %d\n", branchTo);
exit(0);
}
S.restrictedPickBranch = branchTo;
} else if ((value = hasPrefix(argv[i], "--restarts="))) {
uint maxrest;
if (sscanf(value, "%d", &maxrest) < 0 || maxrest == 0) {
printf("ERROR! illegal maximum restart number %d\n", maxrest);
exit(0);
}
S.setMaxRestarts(maxrest);
} else if ((value = hasPrefix(argv[i], "--dumplearnts="))) {
if (sscanf(value, "%400s", learnts_filename) < 0 || strlen(learnts_filename) == 0) {
printf("ERROR! wrong filename '%s'\n", learnts_filename);
exit(0);
}
dumpLearnts = true;
} else if ((value = hasPrefix(argv[i], "--maxdumplearnts="))) {
if (!dumpLearnts) {
printf("ERROR! -dumplearnts=<filename> must be first activated before issuing -maxdumplearnts=<size>\n");
exit(0);
}
int tmp;
if (sscanf(value, "%d", &tmp) < 0 || tmp < 0) {
cout << "ERROR! wrong maximum dumped learnt clause size is illegal: " << tmp << endl;
exit(0);
}
maxLearntsSize = (uint32_t)tmp;
} else if ((value = hasPrefix(argv[i], "--maxsolutions="))) {
int tmp;
if (sscanf(value, "%d", &tmp) < 0 || tmp < 0) {
cout << "ERROR! wrong maximum number of solutions is illegal: " << tmp << endl;
exit(0);
}
max_nr_of_solutions = (uint32_t)tmp;
#ifdef USE_GAUSS
} else if ((value = hasPrefix(argv[i], "--gaussuntil="))) {
uint32_t until;
if (sscanf(value, "%d", &until) < 0) {
printf("ERROR! until %s\n", value);
exit(0);
}
S.gaussconfig.decision_until = until;
} else if ((value = hasPrefix(argv[i], "--nodisablegauss"))) {
S.gaussconfig.dontDisable = true;
} else if ((value = hasPrefix(argv[i], "--nomatrixfind"))) {
S.gaussconfig.noMatrixFind = true;
} else if ((value = hasPrefix(argv[i], "--noiterreduce"))) {
S.gaussconfig.iterativeReduce = false;
} else if ((value = hasPrefix(argv[i], "--noordercol"))) {
S.gaussconfig.orderCols = false;
} else if ((value = hasPrefix(argv[i], "--maxmatrixrows"))) {
uint32_t rows;
if (sscanf(value, "%d", &rows) < 0) {
printf("ERROR! maxmatrixrows: %s\n", value);
exit(0);
}
S.gaussconfig.maxMatrixRows = rows;
} else if ((value = hasPrefix(argv[i], "--minmatrixrows"))) {
uint32_t rows;
if (sscanf(value, "%d", &rows) < 0) {
printf("ERROR! minmatrixrows: %s\n", value);
exit(0);
}
S.gaussconfig.minMatrixRows = rows;
} else if ((value = hasPrefix(argv[i], "--savematrix"))) {
uint32_t every;
if (sscanf(value, "%d", &every) < 0) {
printf("ERROR! savematrix: %s\n", value);
exit(0);
}
cout << "c Matrix saved every " << every << " decision levels" << endl;
S.gaussconfig.only_nth_gauss_save = every;
#endif //USE_GAUSS
} else if ((value = hasPrefix(argv[i], "--greedyunbound"))) {
S.greedyUnbound = true;
} else if ((value = hasPrefix(argv[i], "--nonormxorfind"))) {
S.findNormalXors = false;
} else if ((value = hasPrefix(argv[i], "--nobinxorfind"))) {
S.findBinaryXors = false;
} else if ((value = hasPrefix(argv[i], "--noregbxorfind"))) {
S.regularlyFindBinaryXors = false;
} else if ((value = hasPrefix(argv[i], "--noconglomerate"))) {
S.conglomerateXors = false;
} else if ((value = hasPrefix(argv[i], "--nosimplify"))) {
S.schedSimplification = false;
} else if ((value = hasPrefix(argv[i], "--debuglib"))) {
debugLib = true;
} else if ((value = hasPrefix(argv[i], "--debugnewvar"))) {
debugNewVar = true;
} else if ((value = hasPrefix(argv[i], "--novarreplace"))) {
S.performReplace = false;
} else if ((value = hasPrefix(argv[i], "--nofailedvar"))) {
S.failedVarSearch = false;
} else if ((value = hasPrefix(argv[i], "--noheuleprocess"))) {
S.heuleProcess = false;
} else if ((value = hasPrefix(argv[i], "--nosatelite"))) {
S.doSubsumption = false;
} else if ((value = hasPrefix(argv[i], "--noparthandler"))) {
S.doPartHandler = false;
} else if ((value = hasPrefix(argv[i], "--noxorsubs"))) {
S.doXorSubsumption = false;
} else if ((value = hasPrefix(argv[i], "--nohyperbinres"))) {
S.doHyperBinRes = false;
} else if ((value = hasPrefix(argv[i], "--noblockedclause"))) {
S.doBlockedClause = false;
} else if ((value = hasPrefix(argv[i], "--novarelim"))) {
S.doVarElim = false;
} else if ((value = hasPrefix(argv[i], "--nosubsume1"))) {
S.doSubsume1 = false;
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0) {
printUsage(argv, S);
exit(0);
} else if ((value = hasPrefix(argv[i], "--restart="))) {
if (strcmp(value, "auto") == 0)
S.fixRestartType = auto_restart;
else if (strcmp(value, "static") == 0)
S.fixRestartType = static_restart;
else if (strcmp(value, "dynamic") == 0)
S.fixRestartType = dynamic_restart;
else {
printf("ERROR! unknown restart type %s\n", value);
exit(0);
}
} else if ((value = hasPrefix(argv[i], "--nosolprint"))) {
printResult = false;
//} else if ((value = hasPrefix(argv[i], "--addoldlearnts"))) {
// S.readdOldLearnts = true;
} else if ((value = hasPrefix(argv[i], "--noextrabins"))) {
S.addExtraBins = false;
} else if ((value = hasPrefix(argv[i], "--noremovebins"))) {
S.removeUselessBins = false;
} else if ((value = hasPrefix(argv[i], "--noregremovebins"))) {
S.regularRemoveUselessBins = false;
} else if ((value = hasPrefix(argv[i], "--nosubswithbins"))) {
S.subsumeWithNonExistBinaries = false;
} else if ((value = hasPrefix(argv[i], "--norsubswithbins"))) {
S.regularSubsumeWithNonExistBinaries = false;
} else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0) {
printf("ERROR! unknown flag %s\n", argv[i]);
exit(0);
} else
argv[j++] = argv[i];
}
argc = j;
if (!debugLib) S.libraryUsage = false;
if (S.verbosity >= 1)
printf("c This is CryptoMiniSat %s\n", VERSION);
#if defined(__linux__)
fpu_control_t oldcw, newcw;
_FPU_GETCW(oldcw);
newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
_FPU_SETCW(newcw);
if (S.verbosity >= 1) printf("c WARNING: for repeatability, setting FPU to use double precision\n");
#endif
double cpu_time = cpuTime();
solver = &S;
signal(SIGINT,SIGINT_handler);
//signal(SIGHUP,SIGINT_handler);
if (argc == 1)
printf("c Reading from standard input... Use '-h' or '--help' for help.\n");
#ifdef DISABLE_ZLIB
FILE * in = (argc == 1) ? fopen(0, "rb") : fopen(argv[1], "rb");
#else
gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
#endif // DISABLE_ZLIB
if (in == NULL) {
printf("ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]);
exit(1);
}
if (S.verbosity >= 1) {
printf("c =================================[ Problem Statistics ]==================================\n");
printf("c | |\n");
}
parse_DIMACS(in, S);
#ifdef DISABLE_ZLIB
fclose(in);
#else
gzclose(in);
#endif // DISABLE_ZLIB
if (argc >= 3)
printf("c Outputting solution to file: %s\n" , argv[2]);
double parse_time = cpuTime() - cpu_time;
if (S.verbosity >= 1)
printf("c | Parsing time: %-12.2f s |\n", parse_time);
lbool ret;
while(1)
{
ret = S.solve();
if ( ret != l_True ) break;
std::cout << "c " << std::setw(8) << current_nr_of_solutions++ << " solution(s) found" << std::endl;
if (current_nr_of_solutions > max_nr_of_solutions) break;
printf("c Prepare for next run...\n");
vec<Lit> lits;
if (printResult) printf("v ");
for (Var var = 0; var != S.nVars(); var++) {
if (S.model[var] != l_Undef) {
lits.push( Lit(var, (S.model[var] == l_True)? true : false) );
if (printResult) printf("%s%d ", (S.model[var] == l_True)? "" : "-", var+1);
}
}
if (printResult) printf("\n");
S.addClause(lits);
}
printStats(S);
printf("c \n");
if (dumpLearnts) {
S.dumpSortedLearnts(learnts_filename, maxLearntsSize);
cout << "c Sorted learnt clauses dumped to file '" << learnts_filename << "'" << endl;
}
if (ret == l_Undef)
printf("c Not finished running -- maximum restart reached\n");
FILE* res = NULL;
if (argc >= 3) {
res = fopen(argv[2], "wb");
if (res == NULL) {
int backup_errno = errno;
printf("Cannot open %s for writing. Problem: %s", argv[2], strerror(backup_errno));
exit(1);
}
}
if (res != NULL) {
if (ret == l_True) {
printf("c SAT\n");
fprintf(res, "SAT\n");
if (printResult) {
for (Var var = 0; var != S.nVars(); var++)
if (S.model[var] != l_Undef)
fprintf(res, "%s%d ", (S.model[var] == l_True)? "" : "-", var+1);
fprintf(res, "0\n");
}
} else if (ret == l_False) {
printf("c UNSAT\n");
fprintf(res, "UNSAT\n");
} else {
printf("c INCONCLUSIVE\n");
fprintf(res, "INCONCLUSIVE\n");
}
fclose(res);
} else {
if (ret == l_True)
printf("s SATISFIABLE\n");
else if (ret == l_False)
printf("s UNSATISFIABLE\n");
if(ret == l_True && printResult) {
printf("v ");
for (Var var = 0; var != S.nVars(); var++)
if (S.model[var] != l_Undef)
printf("%s%d ", (S.model[var] == l_True)? "" : "-", var+1);
printf("0\n");
}
}
#ifdef NDEBUG
exit(ret == l_True ? 10 : 20); // (faster than "return", which will invoke the destructor for 'Solver')
#endif
if (ret == l_True) return 10;
if (ret == l_False) return 20;
if (ret == l_Undef) return 15;
assert(false);
return 0;
}

View File

@ -0,0 +1,16 @@
noinst_LTLIBRARIES = libcryptominisat.la
AM_CXXFLAGS = -Wall $(all_includes) -I$(srcdir) -I$(srcdir)/../MTRand -I$(srcdir)/../mtl
libcryptominisat_la_SOURCES = \
ClauseCleaner.cpp FailedVarSearcher.cpp Logger.cpp \
PartFinder.cpp SmallPtr.cpp VarReplacer.cpp \
Clause.cpp FindUndef.cpp MatrixFinder.cpp \
PartHandler.cpp Solver.cpp XorFinder.cpp \
PackedRow.cpp Gaussian.cpp StateSaver.cpp \
RestartTypeChooser.cpp Subsumer.cpp XorSubsumer.cpp
bin_PROGRAMS = cryptominisat
cryptominisat_LDADD = libcryptominisat.la
cryptominisat_LDFLAGS = -lz
cryptominisat_SOURCES = Main.C

View File

@ -0,0 +1,588 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = cryptominisat$(EXEEXT)
subdir = Solver
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4-extra/boost.m4 $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libcryptominisat_la_LIBADD =
am_libcryptominisat_la_OBJECTS = ClauseCleaner.lo FailedVarSearcher.lo \
Logger.lo PartFinder.lo SmallPtr.lo VarReplacer.lo Clause.lo \
FindUndef.lo MatrixFinder.lo PartHandler.lo Solver.lo \
XorFinder.lo PackedRow.lo Gaussian.lo StateSaver.lo \
RestartTypeChooser.lo Subsumer.lo XorSubsumer.lo
libcryptominisat_la_OBJECTS = $(am_libcryptominisat_la_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_cryptominisat_OBJECTS = Main.$(OBJEXT)
cryptominisat_OBJECTS = $(am_cryptominisat_OBJECTS)
cryptominisat_DEPENDENCIES = libcryptominisat.la
cryptominisat_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(cryptominisat_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libcryptominisat_la_SOURCES) $(cryptominisat_SOURCES)
DIST_SOURCES = $(libcryptominisat_la_SOURCES) $(cryptominisat_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
BOOST_ROOT = @BOOST_ROOT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LTLIBRARIES = libcryptominisat.la
AM_CXXFLAGS = -Wall $(all_includes) -I$(srcdir) -I$(srcdir)/../MTRand -I$(srcdir)/../mtl
libcryptominisat_la_SOURCES = \
ClauseCleaner.cpp FailedVarSearcher.cpp Logger.cpp \
PartFinder.cpp SmallPtr.cpp VarReplacer.cpp \
Clause.cpp FindUndef.cpp MatrixFinder.cpp \
PartHandler.cpp Solver.cpp XorFinder.cpp \
PackedRow.cpp Gaussian.cpp StateSaver.cpp \
RestartTypeChooser.cpp Subsumer.cpp XorSubsumer.cpp
cryptominisat_LDADD = libcryptominisat.la
cryptominisat_LDFLAGS = -lz
cryptominisat_SOURCES = Main.C
all: all-am
.SUFFIXES:
.SUFFIXES: .C .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Solver/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Solver/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libcryptominisat.la: $(libcryptominisat_la_OBJECTS) $(libcryptominisat_la_DEPENDENCIES)
$(CXXLINK) $(libcryptominisat_la_OBJECTS) $(libcryptominisat_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p || test -f $$p1; \
then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' `; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
cryptominisat$(EXEEXT): $(cryptominisat_OBJECTS) $(cryptominisat_DEPENDENCIES)
@rm -f cryptominisat$(EXEEXT)
$(cryptominisat_LINK) $(cryptominisat_OBJECTS) $(cryptominisat_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Clause.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClauseCleaner.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FailedVarSearcher.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FindUndef.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Gaussian.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Logger.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MatrixFinder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PackedRow.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PartFinder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PartHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RestartTypeChooser.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SmallPtr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Solver.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StateSaver.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Subsumer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VarReplacer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XorFinder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XorSubsumer.Plo@am__quote@
.C.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.C.obj:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.C.lo:
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
.cpp.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-libtool \
clean-noinstLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-binPROGRAMS
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic clean-libtool clean-noinstLTLIBRARIES ctags \
distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-binPROGRAMS \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-binPROGRAMS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -0,0 +1,247 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "constants.h"
#ifdef USE_GAUSS
#include "MatrixFinder.h"
#include "Solver.h"
#include "Gaussian.h"
#include "GaussianConfig.h"
#include "ClauseCleaner.h"
#include "time_mem.h"
#include <set>
#include <map>
#include <iomanip>
#include <math.h>
using std::set;
using std::map;
//#define VERBOSE_DEBUG
using std::cout;
using std::endl;
//#define PART_FINDING
MatrixFinder::MatrixFinder(Solver& _solver) :
solver(_solver)
{
}
inline const Var MatrixFinder::fingerprint(const XorClause& c) const
{
Var fingerprint = 0;
for (const Lit* a = &c[0], *end = a + c.size(); a != end; a++)
fingerprint |= a->var();
return fingerprint;
}
inline const bool MatrixFinder::firstPartOfSecond(const XorClause& c1, const XorClause& c2) const
{
uint i1, i2;
for (i1 = 0, i2 = 0; i1 < c1.size() && i2 < c2.size();) {
if (c1[i1].var() != c2[i2].var())
i2++;
else {
i1++;
i2++;
}
}
return (i1 == c1.size());
}
const bool MatrixFinder::findMatrixes()
{
table.clear();
table.resize(solver.nVars(), var_Undef);
reverseTable.clear();
matrix_no = 0;
double myTime = cpuTime();
if (solver.xorclauses.size() < MIN_GAUSS_XOR_CLAUSES ||
solver.gaussconfig.decision_until <= 0 ||
solver.xorclauses.size() > MAX_GAUSS_XOR_CLAUSES
)
return true;
solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses);
if (!solver.ok) return false;
if (solver.gaussconfig.noMatrixFind) {
if (solver.verbosity >=1)
cout << "c | Matrix finding disabled through switch. Putting all xors into matrix." << endl;
vector<XorClause*> xorclauses;
xorclauses.reserve(solver.xorclauses.size());
for (uint32_t i = 0; i < solver.xorclauses.size(); i++)
xorclauses.push_back(solver.xorclauses[i]);
solver.gauss_matrixes.push_back(new Gaussian(solver, solver.gaussconfig, 0, xorclauses));
return true;
}
for (XorClause** c = solver.xorclauses.getData(), **end = c + solver.xorclauses.size(); c != end; c++) {
set<uint> tomerge;
vector<Var> newSet;
for (Lit *l = &(**c)[0], *end2 = l + (**c).size(); l != end2; l++) {
if (table[l->var()] != var_Undef)
tomerge.insert(table[l->var()]);
else
newSet.push_back(l->var());
}
if (tomerge.size() == 1) {
const uint into = *tomerge.begin();
map<uint, vector<Var> >::iterator intoReverse = reverseTable.find(into);
for (uint i = 0; i < newSet.size(); i++) {
intoReverse->second.push_back(newSet[i]);
table[newSet[i]] = into;
}
continue;
}
for (set<uint>::iterator it = tomerge.begin(); it != tomerge.end(); it++) {
newSet.insert(newSet.end(), reverseTable[*it].begin(), reverseTable[*it].end());
reverseTable.erase(*it);
}
for (uint i = 0; i < newSet.size(); i++)
table[newSet[i]] = matrix_no;
reverseTable[matrix_no] = newSet;
matrix_no++;
}
#ifdef VERBOSE_DEBUG
for (map<uint, vector<Var> >::iterator it = reverseTable.begin(), end = reverseTable.end(); it != end; it++) {
cout << "-- set begin --" << endl;
for (vector<Var>::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) {
cout << *it2 << ", ";
}
cout << "-------" << endl;
}
#endif
uint32_t numMatrixes = setMatrixes();
if (solver.verbosity >=1)
std::cout << "c | Finding matrixes : " << cpuTime() - myTime << " s (found " << numMatrixes << ") |" << endl;
for (vector<Gaussian*>::iterator gauss = solver.gauss_matrixes.begin(), end = solver.gauss_matrixes.end(); gauss != end; gauss++) {
if (!(*gauss)->full_init()) return false;
}
return true;
}
const uint MatrixFinder::setMatrixes()
{
vector<pair<uint, uint> > numXorInMatrix;
for (uint i = 0; i < matrix_no; i++)
numXorInMatrix.push_back(std::make_pair(i, 0));
vector<uint> sumXorSizeInMatrix(matrix_no, 0);
vector<vector<uint> > xorSizesInMatrix(matrix_no);
vector<vector<XorClause*> > xorsInMatrix(matrix_no);
#ifdef PART_FINDING
vector<vector<Var> > xorFingerprintInMatrix(matrix_no);
#endif
for (XorClause** c = solver.xorclauses.getData(), **end = c + solver.xorclauses.size(); c != end; c++) {
XorClause& x = **c;
const uint matrix = table[x[0].var()];
assert(matrix < matrix_no);
//for stats
numXorInMatrix[matrix].second++;
sumXorSizeInMatrix[matrix] += x.size();
xorSizesInMatrix[matrix].push_back(x.size());
xorsInMatrix[matrix].push_back(&x);
#ifdef PART_FINDING
xorFingerprintInMatrix[matrix].push_back(fingerprint(x));
#endif //PART_FINDING
}
std::sort(numXorInMatrix.begin(), numXorInMatrix.end(), mysorter());
#ifdef PART_FINDING
for (uint i = 0; i < matrix_no; i++)
findParts(xorFingerprintInMatrix[i], xorsInMatrix[i]);
#endif //PART_FINDING
uint realMatrixNum = 0;
for (int a = matrix_no-1; a != -1; a--) {
uint i = numXorInMatrix[a].first;
if (numXorInMatrix[a].second < 3)
continue;
const uint totalSize = reverseTable[i].size()*numXorInMatrix[a].second;
const double density = (double)sumXorSizeInMatrix[i]/(double)totalSize*100.0;
double avg = (double)sumXorSizeInMatrix[i]/(double)numXorInMatrix[a].second;
double variance = 0.0;
for (uint i2 = 0; i2 < xorSizesInMatrix[i].size(); i2++)
variance += pow((double)xorSizesInMatrix[i][i2]-avg, 2);
variance /= (double)xorSizesInMatrix.size();
const double stdDeviation = sqrt(variance);
if (numXorInMatrix[a].second >= solver.gaussconfig.minMatrixRows
&& numXorInMatrix[a].second <= solver.gaussconfig.maxMatrixRows
&& realMatrixNum < 3)
{
if (solver.verbosity >=1)
cout << "c | Matrix no " << std::setw(2) << realMatrixNum;
solver.gauss_matrixes.push_back(new Gaussian(solver, solver.gaussconfig, realMatrixNum, xorsInMatrix[i]));
realMatrixNum++;
} else {
if (solver.verbosity >=1 /*&& numXorInMatrix[a].second >= 20*/)
cout << "c | Unused Matrix ";
}
if (solver.verbosity >=1 /*&& numXorInMatrix[a].second >= 20*/) {
cout << std::setw(7) << numXorInMatrix[a].second << " x" << std::setw(5) << reverseTable[i].size();
cout << " density:" << std::setw(5) << std::fixed << std::setprecision(1) << density << "%";
cout << " xorlen avg:" << std::setw(5) << std::fixed << std::setprecision(2) << avg;
cout << " stdev:" << std::setw(6) << std::fixed << std::setprecision(2) << stdDeviation << " |" << endl;
}
}
return realMatrixNum;
}
void MatrixFinder::findParts(vector<Var>& xorFingerprintInMatrix, vector<XorClause*>& xorsInMatrix)
{
uint ai = 0;
for (XorClause **a = &xorsInMatrix[0], **end = a + xorsInMatrix.size(); a != end; a++, ai++) {
const Var fingerprint = xorFingerprintInMatrix[ai];
uint ai2 = 0;
for (XorClause **a2 = &xorsInMatrix[0]; a2 != end; a2++, ai2++) {
if (ai == ai2) continue;
const Var fingerprint2 = xorFingerprintInMatrix[ai2];
if (((fingerprint & fingerprint2) == fingerprint) && firstPartOfSecond(**a, **a2)) {
cout << "First part of second:" << endl;
(*a)->plainPrint();
(*a2)->plainPrint();
cout << "END" << endl;
}
}
}
}
#endif //USE_GAUSS

View File

@ -0,0 +1,67 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef MATRIXFINDER_H
#define MATRIXFINDER_H
#include <vector>
#include <map>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "Clause.h"
#include "Solver.h"
class Solver;
using std::map;
using std::vector;
using std::pair;
class MatrixFinder {
public:
MatrixFinder(Solver& solver);
const bool findMatrixes();
private:
const uint setMatrixes();
struct mysorter
{
bool operator () (const pair<uint, uint>& left, const pair<uint, uint>& right)
{
return left.second < right.second;
}
};
void findParts(vector<Var>& xorFingerprintInMatrix, vector<XorClause*>& xorsInMatrix);
inline const Var fingerprint(const XorClause& c) const;
inline const bool firstPartOfSecond(const XorClause& c1, const XorClause& c2) const;
map<uint, vector<Var> > reverseTable; //matrix -> vars
vector<Var> table; //var -> matrix
uint matrix_no;
Solver& solver;
};
#endif //MATRIXFINDER_H

View File

@ -0,0 +1,218 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef PACKEDMATRIX_H
#define PACKEDMATRIX_H
#include <algorithm>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "PackedRow.h"
//#define DEBUG_MATRIX
class PackedMatrix
{
public:
PackedMatrix() :
mp(NULL)
, numRows(0)
, numCols(0)
{
}
PackedMatrix(const PackedMatrix& b) :
numRows(b.numRows)
, numCols(b.numCols)
{
#ifdef DEBUG_MATRIX
assert(b.numRows > 0 && b.numCols > 0);
#endif
mp = new uint64_t[numRows*2*(numCols+1)];
memcpy(mp, b.mp, sizeof(uint64_t)*numRows*2*(numCols+1));
}
~PackedMatrix()
{
delete[] mp;
}
void resize(const uint num_rows, uint num_cols)
{
num_cols = num_cols / 64 + (bool)(num_cols % 64);
if (numRows*2*(numCols+1) < num_rows*2*(num_cols+1)) {
delete[] mp;
mp = new uint64_t[num_rows*2*(num_cols+1)];
}
numRows = num_rows;
numCols = num_cols;
}
void resizeNumRows(const uint num_rows)
{
#ifdef DEBUG_MATRIX
assert(num_rows <= numRows);
#endif
numRows = num_rows;
}
PackedMatrix& operator=(const PackedMatrix& b)
{
#ifdef DEBUG_MATRIX
//assert(b.numRows > 0 && b.numCols > 0);
#endif
if (numRows*2*(numCols+1) < b.numRows*2*(b.numCols+1)) {
delete[] mp;
mp = new uint64_t[b.numRows*2*(b.numCols+1)];
}
numRows = b.numRows;
numCols = b.numCols;
memcpy(mp, b.mp, sizeof(uint64_t)*numRows*2*(numCols+1));
return *this;
}
inline PackedRow getMatrixAt(const uint i)
{
#ifdef DEBUG_MATRIX
assert(i <= numRows);
#endif
return PackedRow(numCols, mp+i*2*(numCols+1));
}
inline PackedRow getVarsetAt(const uint i)
{
#ifdef DEBUG_MATRIX
assert(i <= numRows);
#endif
return PackedRow(numCols, mp+i*2*(numCols+1)+(numCols+1));
}
inline const PackedRow getMatrixAt(const uint i) const
{
#ifdef DEBUG_MATRIX
assert(i <= numRows);
#endif
return PackedRow(numCols, mp+i*2*(numCols+1));
}
inline const PackedRow getVarsetAt(const uint i) const
{
#ifdef DEBUG_MATRIX
assert(i <= numRows);
#endif
return PackedRow(numCols, mp+i*2*(numCols+1)+(numCols+1));
}
class iterator
{
public:
PackedRow operator*()
{
return PackedRow(numCols, mp);
}
iterator& operator++()
{
mp += 2*(numCols+1);
return *this;
}
iterator operator+(const uint num) const
{
iterator ret(*this);
ret.mp += 2*(numCols+1)*num;
return ret;
}
const uint operator-(const iterator& b) const
{
return (mp - b.mp)/(2*(numCols+1));
}
void operator+=(const uint num)
{
mp += 2*(numCols+1)*num;
}
const bool operator!=(const iterator& it) const
{
return mp != it.mp;
}
const bool operator==(const iterator& it) const
{
return mp == it.mp;
}
private:
friend class PackedMatrix;
iterator(uint64_t* _mp, const uint _numCols) :
mp(_mp)
, numCols(_numCols)
{}
uint64_t* mp;
const uint numCols;
};
inline iterator beginMatrix()
{
return iterator(mp, numCols);
}
inline iterator endMatrix()
{
return iterator(mp+numRows*2*(numCols+1), numCols);
}
inline iterator beginVarset()
{
return iterator(mp+(numCols+1), numCols);
}
inline iterator endVarset()
{
return iterator(mp+(numCols+1)+numRows*2*(numCols+1), numCols);
}
inline const uint getSize() const
{
return numRows;
}
private:
uint64_t* mp;
uint numRows;
uint numCols;
};
#endif //PACKEDMATRIX_H

View File

@ -0,0 +1,115 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "PackedRow.h"
std::ostream& operator << (std::ostream& os, const PackedRow& m)
{
for(uint32_t i = 0; i < m.size*64; i++) {
os << m[i];
}
os << " -- xor: " << m.is_true();
return os;
}
bool PackedRow::operator ==(const PackedRow& b) const
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(size == b.size);
#endif
return (std::equal(b.mp-1, b.mp+size, mp-1));
}
bool PackedRow::operator !=(const PackedRow& b) const
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(size == b.size);
#endif
return (!std::equal(b.mp-1, b.mp+size, mp-1));
}
uint32_t PackedRow::popcnt() const
{
uint32_t popcnt = 0;
for (uint32_t i = 0; i < size; i++) if (mp[i]) {
uint64_t tmp = mp[i];
for (uint i2 = 0; i2 < 64; i2++) {
popcnt += (tmp & 1);
tmp >>= 1;
}
}
return popcnt;
}
uint32_t PackedRow::popcnt(const uint32_t from) const
{
uint32_t popcnt = 0;
for (uint32_t i = from/64; i != size; i++) if (mp[i]) {
uint64_t tmp = mp[i];
uint32_t i2;
if (i == from/64) {
i2 = from%64;
tmp >>= i2;
} else
i2 = 0;
for (; i2 < 64; i2++) {
popcnt += (tmp & 1);
tmp >>= 1;
}
}
return popcnt;
}
void PackedRow::fill(vec<Lit>& tmp_clause, const vec<lbool>& assigns, const vector<Var>& col_to_var_original) const
{
bool final = !is_true_internal;
tmp_clause.clear();
uint32_t col = 0;
bool wasundef = false;
for (uint32_t i = 0; i < size; i++) for (uint32_t i2 = 0; i2 < 64; i2++) {
if ((mp[i] >> i2) &1) {
const Var& var = col_to_var_original[col];
assert(var != std::numeric_limits<Var>::max());
const lbool& val = assigns[var];
const bool val_bool = val.getBool();
tmp_clause.push(Lit(var, val_bool));
final ^= val_bool;
if (val.isUndef()) {
assert(!wasundef);
Lit tmp(tmp_clause[0]);
tmp_clause[0] = tmp_clause.last();
tmp_clause.last() = tmp;
wasundef = true;
}
}
col++;
}
if (wasundef) {
tmp_clause[0] ^= final;
//assert(ps != ps_first+1);
} else
assert(!final);
}

View File

@ -0,0 +1,234 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef PACKEDROW_H
#define PACKEDROW_H
//#define DEBUG_ROW
#include <vector>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "SolverTypes.h"
#include "Vec.h"
#include <string.h>
#include <iostream>
#include <algorithm>
#include <limits>
#ifndef uint
#define uint unsigned int
#endif
using std::vector;
class PackedMatrix;
class PackedRow
{
public:
bool operator ==(const PackedRow& b) const;
bool operator !=(const PackedRow& b) const;
PackedRow& operator=(const PackedRow& b)
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(size == b.size);
#endif
memcpy(mp-1, b.mp-1, size+1);
return *this;
}
PackedRow& operator^=(const PackedRow& b)
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(b.size == size);
#endif
for (uint32_t i = 0; i != size; i++) {
*(mp + i) ^= *(b.mp + i);
}
is_true_internal ^= b.is_true_internal;
return *this;
}
void xorBoth(const PackedRow& b)
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(b.size == size);
#endif
for (uint32_t i = 0; i != 2*size+1; i++) {
*(mp + i) ^= *(b.mp + i);
}
is_true_internal ^= b.is_true_internal;
}
uint32_t popcnt() const;
uint32_t popcnt(uint32_t from) const;
bool popcnt_is_one() const
{
char popcount = 0;
for (uint32_t i = 0; i != size; i++) {
uint64_t tmp = mp[i];
while(tmp) {
popcount += tmp & 1;
tmp >>= 1;
}
}
return popcount == 1;
}
bool popcnt_is_one(uint32_t from) const
{
from++;
uint64_t tmp = mp[from/64];
tmp >>= from%64;
if (tmp) return false;
for (uint32_t i = from/64+1; i != size; i++)
if (mp[i]) return false;
return true;
}
inline const uint64_t& is_true() const
{
return is_true_internal;
}
inline const bool isZero() const
{
for (uint32_t i = 0; i != size; i++) {
if (mp[i]) return false;
}
return true;
}
inline void setZero()
{
memset(mp, 0, sizeof(uint64_t)*size);
}
inline void clearBit(const uint32_t i)
{
mp[i/64] &= ~((uint64_t)1 << (i%64));
}
inline void invert_is_true(const bool b = true)
{
is_true_internal ^= (uint64_t)b;
}
inline void setBit(const uint32_t i)
{
mp[i/64] |= ((uint64_t)1 << (i%64));
}
void swapBoth(PackedRow b)
{
#ifdef DEBUG_ROW
assert(size > 0);
assert(b.size > 0);
assert(b.size == size);
#endif
uint64_t * __restrict mp1 = mp-1;
uint64_t * __restrict mp2 = b.mp-1;
uint32_t i = 2*(size+1);
while(i != 0) {
std::swap(*mp1, *mp2);
mp1++;
mp2++;
i--;
}
}
inline const bool operator[](const uint32_t& i) const
{
#ifdef DEBUG_ROW
assert(size*64 > i);
#endif
return (mp[i/64] >> (i%64)) & 1;
}
template<class T>
void set(const T& v, const vector<uint16_t>& var_to_col, const uint32_t matrix_size)
{
assert(size == (matrix_size/64) + ((bool)(matrix_size % 64)));
//mp = new uint64_t[size];
setZero();
for (uint32_t i = 0; i != v.size(); i++) {
const uint32_t toset_var = var_to_col[v[i].var()];
assert(toset_var != std::numeric_limits<uint32_t>::max());
setBit(toset_var);
}
is_true_internal = !v.xor_clause_inverted();
}
void fill(vec<Lit>& tmp_clause, const vec<lbool>& assigns, const vector<Var>& col_to_var_original) const;
inline unsigned long int scan(const unsigned long int var) const
{
#ifdef DEBUG_ROW
assert(size > 0);
#endif
for(uint32_t i = var; i != size*64; i++)
if (this->operator[](i)) return i;
return std::numeric_limits<unsigned long int>::max();
}
friend std::ostream& operator << (std::ostream& os, const PackedRow& m);
private:
friend class PackedMatrix;
PackedRow(const uint32_t _size, uint64_t* const _mp) :
mp(_mp+1)
, is_true_internal(*_mp)
, size(_size)
{}
uint64_t* __restrict const mp;
uint64_t& is_true_internal;
const uint32_t size;
};
std::ostream& operator << (std::ostream& os, const PackedRow& m);
#endif //PACKEDROW_H

View File

@ -0,0 +1,179 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "PartFinder.h"
#include "Solver.h"
#include "ClauseCleaner.h"
#include "time_mem.h"
#include "VarReplacer.h"
#include <set>
#include <map>
#include <iomanip>
#include <math.h>
#include "FailedVarSearcher.h"
using std::set;
using std::map;
//#define VERBOSE_DEBUG
using std::cout;
using std::endl;
//#define PART_FINDING
PartFinder::PartFinder(Solver& _solver) :
solver(_solver)
{
}
const bool PartFinder::findParts()
{
assert(solver.performReplace);
double time = cpuTime();
table.clear();
table.resize(solver.nVars(), std::numeric_limits<uint32_t>::max());
reverseTable.clear();
part_no = 0;
solver.clauseCleaner->removeAndCleanAll(true);
if (!solver.ok) return false;
while (solver.varReplacer->getNewToReplaceVars() > 0) {
if (solver.performReplace && !solver.varReplacer->performReplace(true))
return false;
solver.clauseCleaner->removeAndCleanAll(true);
if (!solver.ok) return false;
}
assert(solver.varReplacer->getClauses().size() == 0);
addToPart(solver.clauses);
addToPart(solver.binaryClauses);
addToPart(solver.xorclauses);
const uint parts = setParts();
#ifndef NDEBUG
for (map<uint, vector<Var> >::const_iterator it = reverseTable.begin(); it != reverseTable.end(); it++) {
for (uint i2 = 0; i2 < it->second.size(); i2++) {
assert(table[(it->second)[i2]] == it->first);
}
}
#endif
if (solver.verbosity >= 2 || (solver.verbosity >=1 && parts > 1)) {
std::cout << "c | Found parts: " << std::setw(10) << parts
<< " time: " << std::setprecision(2) << std::setw(4) << cpuTime() - time
<< " s" << std::setw(51) << " |" << std::endl;
}
return true;
}
template<class T>
void PartFinder::addToPart(const vec<T*>& cs)
{
set<uint> tomerge;
vector<Var> newSet;
for (T* const* c = cs.getData(), * const*end = c + cs.size(); c != end; c++) {
if ((*c)->learnt()) continue;
tomerge.clear();
newSet.clear();
for (const Lit *l = (*c)->getData(), *end2 = l + (*c)->size(); l != end2; l++) {
if (table[l->var()] != std::numeric_limits<uint32_t>::max())
tomerge.insert(table[l->var()]);
else
newSet.push_back(l->var());
}
if (tomerge.size() == 1) {
//no trees to merge, only merge the clause into one tree
const uint into = *tomerge.begin();
map<uint, vector<Var> >::iterator intoReverse = reverseTable.find(into);
for (uint i = 0; i < newSet.size(); i++) {
intoReverse->second.push_back(newSet[i]);
table[newSet[i]] = into;
}
continue;
}
for (set<uint>::iterator it = tomerge.begin(); it != tomerge.end(); it++) {
newSet.insert(newSet.end(), reverseTable[*it].begin(), reverseTable[*it].end());
reverseTable.erase(*it);
}
for (uint i = 0; i < newSet.size(); i++)
table[newSet[i]] = part_no;
reverseTable[part_no] = newSet;
part_no++;
}
}
const uint PartFinder::setParts()
{
vector<uint> numClauseInPart(part_no, 0);
vector<uint> sumLitsInPart(part_no, 0);
calcIn(solver.clauses, numClauseInPart, sumLitsInPart);
calcIn(solver.binaryClauses, numClauseInPart, sumLitsInPart);
calcIn(solver.xorclauses, numClauseInPart, sumLitsInPart);
uint parts = 0;
for (uint i = 0; i < numClauseInPart.size(); i++) {
if (sumLitsInPart[i] == 0) continue;
if (solver.verbosity >= 2 || ( solver.verbosity >= 1 && reverseTable.size() > 1) ) {
std::cout << "c | Found part " << std::setw(8) << i
<< " vars: " << std::setw(10) << reverseTable[i].size()
<< " clauses:" << std::setw(10) << numClauseInPart[i]
<< " lits size:" << std::setw(10) << sumLitsInPart[i]
<< std::setw(12) << " | " << std::endl;
}
parts++;
}
if (parts > 1) {
#ifdef VERBOSE_DEBUG
for (map<uint, vector<Var> >::iterator it = reverseTable.begin(), end = reverseTable.end(); it != end; it++) {
cout << "-- set begin --" << endl;
for (vector<Var>::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) {
cout << *it2 << ", ";
}
cout << "-------" << endl;
}
#endif
}
return parts;
}
template<class T>
void PartFinder::calcIn(const vec<T*>& cs, vector<uint>& numClauseInPart, vector<uint>& sumLitsInPart)
{
for (T*const* c = cs.getData(), *const*end = c + cs.size(); c != end; c++) {
if ((*c)->learnt()) continue;
T& x = **c;
const uint part = table[x[0].var()];
assert(part < part_no);
//for stats
numClauseInPart[part]++;
sumLitsInPart[part] += x.size();
}
}

View File

@ -0,0 +1,92 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef PARTFINDER_H
#define PARTFINDER_H
#include <vector>
#include <map>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "Clause.h"
class Solver;
using std::map;
using std::vector;
using std::pair;
class PartFinder {
public:
PartFinder(Solver& solver);
const bool findParts();
const map<uint32_t, vector<Var> >& getReverseTable() const; // part->var
const uint32_t getVarPart(const Var var) const;
const vector<uint32_t>& getTable() const; //var -> part
const vector<Var>& getPartVars(const uint32_t part);
private:
const uint setParts();
template<class T>
void addToPart(const vec<T*>& cs);
struct mysorter
{
bool operator () (const pair<uint, uint>& left, const pair<uint, uint>& right)
{
return left.second < right.second;
}
};
//const bool findParts(vector<Var>& xorFingerprintInMatrix, vector<XorClause*>& xorsInMatrix);
template<class T>
void calcIn(const vec<T*>& cs, vector<uint>& numClauseInPart, vector<uint>& sumLitsInPart);
map<uint32_t, vector<Var> > reverseTable; //part -> vars
vector<uint32_t> table; //var -> part
uint32_t part_no;
Solver& solver;
};
inline const map<uint32_t, vector<Var> >& PartFinder::getReverseTable() const
{
return reverseTable;
}
inline const vector<Var>& PartFinder::getTable() const
{
return table;
}
inline const uint32_t PartFinder::getVarPart(const Var var) const
{
return table[var];
}
inline const vector<Var>& PartFinder::getPartVars(const uint32_t part)
{
return reverseTable[part];
}
#endif //PARTFINDER_H

View File

@ -0,0 +1,330 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "PartHandler.h"
#include "VarReplacer.h"
#include <iostream>
#include <assert.h>
#include <iomanip>
//#define VERBOSE_DEBUG
PartHandler::PartHandler(Solver& s) :
solver(s)
{
}
const bool PartHandler::handle()
{
if (solver.performReplace == false)
return true;
PartFinder partFinder(solver);
if (!partFinder.findParts()) {
#ifdef VERBOSE_DEBUG
std::cout << "c findParts() found UNSAT. Whole problem is unsat." << std::endl;
#endif //VERBOSE_DEBUG
return false;
}
uint32_t num_parts = partFinder.getReverseTable().size();
if (num_parts == 1)
return true;
map<uint32_t, vector<Var> > reverseTable = partFinder.getReverseTable();
assert(num_parts == partFinder.getReverseTable().size());
vector<pair<uint32_t, uint32_t> > sizes;
for (map<uint32_t, vector<Var> >::iterator it = reverseTable.begin(); it != reverseTable.end(); it++)
sizes.push_back(std::make_pair(it->first, (uint32_t)it->second.size()));
std::sort(sizes.begin(), sizes.end(), sort_pred());
assert(sizes.size() > 1);
for (uint32_t it = 0; it < sizes.size()-1; it++) {
uint32_t part = sizes[it].first;
vector<Var> vars = reverseTable[part];
if (solver.verbosity >= 1)
std::cout << "c Solving part " << part << std::endl;
Solver newSolver;
newSolver.mtrand.seed(solver.mtrand.randInt());
newSolver.random_var_freq = solver.random_var_freq;
newSolver.verbosity = solver.verbosity;
newSolver.restrictedPickBranch = solver.restrictedPickBranch;
newSolver.greedyUnbound = solver.greedyUnbound;
newSolver.findNormalXors = solver.findNormalXors;
newSolver.findBinaryXors = solver.findBinaryXors;
newSolver.regularlyFindBinaryXors = solver.regularlyFindBinaryXors;
newSolver.conglomerateXors = solver.conglomerateXors;
newSolver.schedSimplification = solver.schedSimplification;
newSolver.performReplace = solver.performReplace;
newSolver.failedVarSearch = solver.failedVarSearch;
#ifdef USE_GAUSS
newSolver.gaussconfig.dontDisable = solver.gaussconfig.dontDisable;
#endif //USE_GAUSS
newSolver.heuleProcess = solver.heuleProcess;
newSolver.doSubsumption = solver.doSubsumption;
newSolver.doPartHandler = solver.doPartHandler;
newSolver.fixRestartType = solver.fixRestartType;
newSolver.var_inc = solver.var_inc;
newSolver.polarity_mode = solver.polarity_mode;
std::sort(vars.begin(), vars.end());
uint32_t i2 = 0;
for (Var var = 0; var < solver.nVars(); var++) {
if (i2 < vars.size() && vars[i2] == var) {
#ifdef VERBOSE_DEBUG
if (!solver.decision_var[var]) {
std::cout << "var " << var + 1 << " is non-decision, but in part... strange." << std::endl;
}
#endif //VERBOSE_DEBUG
newSolver.newVar(solver.decision_var[var]);
newSolver.activity[var] = solver.activity[var];
newSolver.order_heap.update(var);
assert(partFinder.getVarPart(var) == part);
if (solver.decision_var[var]) {
solver.setDecisionVar(var, false);
decisionVarRemoved.push(var);
}
i2++;
} else {
assert(partFinder.getVarPart(var) != part);
newSolver.newVar(false);
}
}
solver.order_heap.filter(Solver::VarFilter(solver));
assert(solver.varReplacer->getClauses().size() == 0);
moveClauses(solver.clauses, newSolver, part, partFinder);
moveClauses(solver.binaryClauses, newSolver, part, partFinder);
moveClauses(solver.xorclauses, newSolver, part, partFinder);
moveLearntClauses(solver.binaryClauses, newSolver, part, partFinder);
moveLearntClauses(solver.learnts, newSolver, part, partFinder);
assert(checkClauseMovement(newSolver, part, partFinder));
lbool status = newSolver.solve();
if (status == l_False) {
#ifdef VERBOSE_DEBUG
std::cout << "c One of the sub-problems was UNSAT. Whole problem is unsat." << std::endl;
#endif //VERBOSE_DEBUG
return false;
}
assert(status != l_Undef);
for (Var var = 0; var < newSolver.nVars(); var++) {
if (newSolver.model[var] != l_Undef) {
assert(solver.assigns[var] == l_Undef);
}
}
assert(newSolver.decisionLevel() == 0);
for (uint32_t i = 0; i < newSolver.trail.size(); i++) {
solver.uncheckedEnqueue(newSolver.trail[i]);
}
solver.ok = (solver.propagate() == NULL);
assert(solver.ok);
for (Var var = 0; var < newSolver.nVars(); var++) {
if (newSolver.model[var] != l_Undef) {
//Must have been decision var in the old solver!??
//assert(std::find(decisionVarRemoved.getData(), decisionVarRemoved.getDataEnd(), var) != decisionVarRemoved.getDataEnd());
assert(savedState[var] == l_Undef);
assert(partFinder.getVarPart(var) == part);
if (newSolver.assigns[var] == l_Undef) {
savedState[var] = newSolver.model[var];
}
}
}
if (solver.verbosity >= 1)
std::cout << "c Solved part" << std::endl;
}
if (solver.verbosity >= 1)
std::cout << "c Coming back to original instance"
<< std::setw(57) << " |" << std::endl;
solver.order_heap.filter(Solver::VarFilter(solver));
//Checking that all variables that are not in the remaining part are all non-decision vars, and none have been set
for (Var var = 0; var < solver.nVars(); var++) {
if (savedState[var] != l_Undef) {
assert(solver.decision_var[var] == false);
assert(solver.assigns[var] == l_Undef || solver.level[var] == 0);
}
}
//Checking that all remaining clauses contain only variables that are in the remaining part
assert(checkClauseMovement(solver, sizes[sizes.size()-1].first, partFinder));
return true;
}
const bool PartHandler::checkClauseMovement(const Solver& thisSolver, const uint32_t part, const PartFinder& partFinder) const
{
if (!checkOnlyThisPart(thisSolver.clauses, part, partFinder))
return false;
if (!checkOnlyThisPart(thisSolver.learnts, part, partFinder))
return false;
if (!checkOnlyThisPart(thisSolver.binaryClauses, part, partFinder))
return false;
if (!checkOnlyThisPart(thisSolver.xorclauses, part, partFinder))
return false;
return true;
}
template<class T>
const bool PartHandler::checkOnlyThisPart(const vec<T*>& cs, const uint32_t part, const PartFinder& partFinder) const
{
for(T * const*it = cs.getData(), * const*end = it + cs.size(); it != end; it++) {
const T& c = **it;
for(const Lit *l = c.getData(), *end2 = l + c.size(); l != end2; l++) {
if (partFinder.getVarPart(l->var()) != part) return false;
}
}
return true;
}
void PartHandler::moveClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder)
{
Clause **i, **j, **end;
for (i = j = cs.getData(), j = i , end = i + cs.size(); i != end; i++) {
if ((**i).learnt() || partFinder.getVarPart((**i)[0].var()) != part) {
*j++ = *i;
continue;
}
solver.detachClause(**i);
#ifdef VERBOSE_DEBUG
std::cout << "clause in this part:"; (**i).plainPrint();
#endif
Clause& c = **i;
vec<Lit> tmp(c.size());
std::copy(c.getData(), c.getDataEnd(), tmp.getData());
newSolver.addClause(tmp, c.getGroup());
//NOTE: we need the CS because otherwise, the addClause could have changed **i, which we need to re-add later!
clausesRemoved.push(*i);
}
cs.shrink(i-j);
}
void PartHandler::moveClauses(vec<XorClause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder)
{
XorClause **i, **j, **end;
for (i = j = cs.getData(), end = i + cs.size(); i != end; i++) {
if (partFinder.getVarPart((**i)[0].var()) != part) {
*j++ = *i;
continue;
}
solver.detachClause(**i);
#ifdef VERBOSE_DEBUG
std::cout << "xor clause in this part:"; (**i).plainPrint();
#endif
XorClause& c = **i;
vec<Lit> tmp(c.size());
std::copy(c.getData(), c.getDataEnd(), tmp.getData());
newSolver.addXorClause(tmp, c.xor_clause_inverted(), c.getGroup());
//NOTE: we need the CS because otherwise, the addXorClause could have changed **i, which we need to re-add later!
xorClausesRemoved.push(*i);
}
cs.shrink(i-j);
}
void PartHandler::moveLearntClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder)
{
Clause **i, **j, **end;
for (i = j = cs.getData(), end = i + cs.size() ; i != end; i++) {
if (!(**i).learnt()) {
*j++ = *i;
continue;
}
Clause& c = **i;
assert(c.size() > 0);
uint32_t clause_part = partFinder.getVarPart(c[0].var());
bool removed = false;
for (const Lit* l = c.getData(), *end = l + c.size(); l != end; l++) {
if (partFinder.getVarPart(l->var()) != clause_part) {
#ifdef VERBOSE_DEBUG
std::cout << "Learnt clause in both parts:"; c.plainPrint();
#endif
removed = true;
solver.removeClause(c);
break;
}
}
if (removed) continue;
if (clause_part == part) {
#ifdef VERBOSE_DEBUG
//std::cout << "Learnt clause in this part:"; c.plainPrint();
#endif
solver.detachClause(c);
newSolver.addLearntClause(c, c.getGroup(), c.activity());
clauseFree(&c);
} else {
#ifdef VERBOSE_DEBUG
std::cout << "Learnt clause in other part:"; c.plainPrint();
#endif
*j++ = *i;
}
}
cs.shrink(i-j);
}
void PartHandler::addSavedState()
{
//Don't add these (non-0-decison-level!) solutions to the 0th decision level
solver.newDecisionLevel();
for (Var var = 0; var < savedState.size(); var++) {
if (savedState[var] != l_Undef) {
assert(solver.assigns[var] == l_Undef);
solver.uncheckedEnqueue(Lit(var, savedState[var] == l_False));
assert(solver.assigns[var] == savedState[var]);
savedState[var] = l_Undef;
solver.polarity[var] = (solver.assigns[var] == l_False);
}
}
for (uint32_t i = 0; i < decisionVarRemoved.size(); i++)
solver.setDecisionVar(decisionVarRemoved[i], true);
decisionVarRemoved.clear();
}
void PartHandler::readdRemovedClauses()
{
FILE* backup_libraryCNFfile = solver.libraryCNFFile;
solver.libraryCNFFile = NULL;
for (Clause **it = clausesRemoved.getData(), **end = clausesRemoved.getDataEnd(); it != end; it++) {
solver.addClause(**it, (*it)->getGroup());
assert(solver.ok);
}
clausesRemoved.clear();
for (XorClause **it = xorClausesRemoved.getData(), **end = xorClausesRemoved.getDataEnd(); it != end; it++) {
solver.addXorClause(**it, (**it).xor_clause_inverted(), (*it)->getGroup());
assert(solver.ok);
}
xorClausesRemoved.clear();
solver.libraryCNFFile = backup_libraryCNFfile;
}

View File

@ -0,0 +1,78 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef PARTHANDLER_H
#define PARTHANDLER_H
#include "Solver.h"
#include "PartFinder.h"
#include "Vec.h"
#include "SolverTypes.h"
#include <map>
#include <vector>
using std::map;
using std::vector;
using std::pair;
class PartHandler
{
public:
PartHandler(Solver& solver);
const bool handle();
const vec<lbool>& getSavedState();
void newVar();
void addSavedState();
void readdRemovedClauses();
private:
struct sort_pred {
bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
return left.second < right.second;
}
};
//For moving clauses
void moveClauses(vec<XorClause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder);
void moveClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder);
void moveLearntClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder);
//Checking moved clauses
const bool checkClauseMovement(const Solver& thisSolver, const uint32_t part, const PartFinder& partFinder) const;
template<class T>
const bool checkOnlyThisPart(const vec<T*>& cs, const uint32_t part, const PartFinder& partFinder) const;
Solver& solver;
vec<lbool> savedState;
vec<Var> decisionVarRemoved; //variables whose decision-ness has been removed
vec<Clause*> clausesRemoved;
vec<XorClause*> xorClausesRemoved;
};
inline const vec<lbool>& PartHandler::getSavedState()
{
return savedState;
}
inline void PartHandler::newVar()
{
savedState.push(l_Undef);
}
#endif //PARTHANDLER_H

View File

@ -0,0 +1,146 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "RestartTypeChooser.h"
#include "Solver.h"
//#define VERBOSE_DEBUG
//#define PRINT_VARS
RestartTypeChooser::RestartTypeChooser(const Solver& s) :
solver(s)
, topX(100)
, limit(40)
{
}
void RestartTypeChooser::addInfo()
{
firstVarsOld = firstVars;
calcHeap();
uint sameIn = 0;
if (!firstVarsOld.empty()) {
uint thisTopX = std::min(firstVarsOld.size(), (size_t)topX);
for (uint i = 0; i != thisTopX; i++) {
if (std::find(firstVars.begin(), firstVars.end(), firstVarsOld[i]) != firstVars.end())
sameIn++;
}
#ifdef VERBOSE_DEBUG
std::cout << " Same vars in first&second first 100: " << sameIn << std::endl;
#endif
sameIns.push_back(sameIn);
}
#ifdef VERBOSE_DEBUG
std::cout << "Avg same vars in first&second first 100: " << avg() << " standard Deviation:" << stdDeviation(sameIns) <<std::endl;
#endif
}
const RestartType RestartTypeChooser::choose()
{
std::pair<double, double> mypair = countVarsDegreeStDev();
if ((mypair.second < 80 &&
(avg() > (double)limit || ((avg() > (double)(limit*0.9) && stdDeviation(sameIns) < 5))))
||
(mypair.second < 80 && (double)solver.xorclauses.size() > (double)solver.nClauses()*0.1))
return static_restart;
else
return dynamic_restart;
}
const double RestartTypeChooser::avg() const
{
double sum = 0.0;
for (uint i = 0; i != sameIns.size(); i++)
sum += sameIns[i];
return (sum/(double)sameIns.size());
}
const double RestartTypeChooser::stdDeviation(vector<uint32_t>& measure) const
{
double average = avg();
double variance = 0.0;
for (uint i = 0; i != measure.size(); i++)
variance += pow((double)measure[i]-average, 2);
variance /= (double)measure.size();
return sqrt(variance);
}
void RestartTypeChooser::calcHeap()
{
firstVars.clear();
firstVars.reserve(topX);
#ifdef PRINT_VARS
std::cout << "First vars:" << std::endl;
#endif
Heap<Solver::VarOrderLt> tmp(solver.order_heap);
uint32_t thisTopX = std::min(tmp.size(), topX);
for (uint32_t i = 0; i != thisTopX; i++) {
#ifdef PRINT_VARS
std::cout << tmp.removeMin()+1 << ", ";
#endif
firstVars.push_back(tmp.removeMin());
}
#ifdef PRINT_VARS
std::cout << std::endl;
#endif
}
const std::pair<double, double> RestartTypeChooser::countVarsDegreeStDev() const
{
vector<uint32_t> degrees;
degrees.resize(solver.nVars(), 0);
addDegrees(solver.clauses, degrees);
addDegrees(solver.binaryClauses, degrees);
addDegrees(solver.xorclauses, degrees);
uint32_t sum = 0;
uint32_t *i = &degrees[0], *j = i;
for (uint32_t *end = i + degrees.size(); i != end; i++) {
if (*i != 0) {
sum += *i;
*j++ = *i;
}
}
degrees.resize(degrees.size() - (i-j));
double avg = (double)sum/(double)degrees.size();
double stdDev = stdDeviation(degrees);
#ifdef VERBOSE_DEBUG
std::cout << "varsDegree avg:" << avg << " stdDev:" << stdDev << std::endl;
#endif
return std::make_pair(avg, stdDev);
}
template<class T>
void RestartTypeChooser::addDegrees(const vec<T*>& cs, vector<uint32_t>& degrees) const
{
for (T * const*c = cs.getData(), * const*end = c + cs.size(); c != end; c++) {
T& cl = **c;
if (cl.learnt()) continue;
for (const Lit *l = cl.getData(), *end2 = l + cl.size(); l != end2; l++) {
degrees[l->var()]++;
}
}
}
template void RestartTypeChooser::addDegrees(const vec<Clause*>& cs, vector<uint32_t>& degrees) const;
template void RestartTypeChooser::addDegrees(const vec<XorClause*>& cs, vector<uint32_t>& degrees) const;

View File

@ -0,0 +1,65 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef RESTARTTYPECHOOSER_H
#define RESTARTTYPECHOOSER_H
#include "Solver.h"
#include <vector>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "SolverTypes.h"
using std::vector;
class Solver;
class RestartTypeChooser
{
public:
RestartTypeChooser(const Solver& s);
void addInfo();
const RestartType choose();
void reset();
private:
void calcHeap();
const double avg() const;
const std::pair<double, double> countVarsDegreeStDev() const;
const double stdDeviation(vector<uint32_t>& measure) const;
template<class T>
void addDegrees(const vec<T*>& cs, vector<uint32_t>& degrees) const;
const Solver& solver;
const uint32_t topX;
const uint32_t limit;
vector<Var> sameIns;
vector<Var> firstVars, firstVarsOld;
};
inline void RestartTypeChooser::reset()
{
sameIns.clear();
}
#endif //RESTARTTYPECHOOSER_H

View File

@ -0,0 +1,12 @@
/*
Please see LICENSE-CPOL.html in the root directory for the licencing of this file.
Originally by: cppnow
Link: http://www.codeproject.com/KB/cpp/smallptr.aspx
*/
#include "SmallPtr.h"
uintptr_t sptr_base::_segs = 1;
//boost::mutex sptr_base::_m;
uintptr_t sptr_base::_seg_map[sptr_base::ALIGNMENT] = { 0 };

View File

@ -0,0 +1,272 @@
/*
Please see LICENSE-CPOL.html in the root directory for the licencing of this file.
Originally by: cppnow
Link: http://www.codeproject.com/KB/cpp/smallptr.aspx
*/
#ifndef __SMALL_PTR_H__
#define __SMALL_PTR_H__
//#include <boost/static_assert.hpp>
#include <cstring>
#include <stdlib.h>
#include "singleton.hpp"
//#include <boost/thread/mutex.hpp>
//#include <boost/thread/locks.hpp>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#define is_n_aligned(T, N) ((sizeof(T) % (N)) == 0)
#ifdef WIN32
# ifdef WIN64
# define USE64
# else
# define USE32
# endif
#endif
#ifdef __GNUG__
# if defined(__amd64__) || defined(__x86_64__)
# define USE64
# elif defined(__i386__)
# define USE32
# endif
#endif
#include <exception>
class bad_alignment : public std::exception
{
public:
bad_alignment(const char *const& w) {}
};
class bad_segment : public std::exception
{
public:
bad_segment(const char *const& w) {}
};
class sptr_base
{
protected:
static const uint32_t ALIGNMENT_BITS = 2;
static const uint32_t ALIGNMENT = (1<<ALIGNMENT_BITS);
static const uintptr_t ALIGNMENT_MASK = ALIGNMENT - 1;
protected:
static uintptr_t _seg_map[ALIGNMENT];
static uintptr_t _segs;
//static boost::mutex _m;
inline static uintptr_t ptr2seg(uintptr_t p)
{
p &= ~0xFFFFFFFFULL; // Keep only high part
uintptr_t s = _segs;
uintptr_t i = 0;
for (; i < s; ++i)
if (_seg_map[i] == p)
return i;
// Not found - now we do it the "right" way (mutex and all)
//boost::lock_guard<boost::mutex> lock(_m);
for (i = 0; i < s; ++i)
if (_seg_map[i] == p)
return i;
i = _segs++;
if (_segs > ALIGNMENT) {
//throw bad_segment("Segment out of range");
exit(-1);
}
_seg_map[i] = p;
return i;
}
};
template<class TYPE>
class sptr : public sptr_base
{
public:
typedef TYPE type;
typedef TYPE* native_pointer_type;
typedef const TYPE* const_native_pointer_type;
sptr() throw()
: _ptr(0)
{}
// Copy constructor
sptr(const sptr<TYPE>& o) throw()
: _ptr(o._ptr)
{
}
// Copy from a related pointer type
// Although just copying _ptr would be more efficient - it may
// also be wrong - e.g. multiple inheritence
template<class O>
sptr(const sptr<O>& o)
: _ptr(encode(static_cast<TYPE*>(o.get())))
{
}
template<class O>
sptr(const O* p)
: _ptr(encode(static_cast<const TYPE*>(p)))
{
}
sptr<TYPE>& operator=(const sptr<TYPE>& o) throw()
{
_ptr = o._ptr;
return *this;
}
template<class O>
sptr<TYPE>& operator=(const sptr<O>& o)
{
_ptr = encode(static_cast<const TYPE*>(o.get()));
return *this;
}
private:
inline uint32_t encode(const_native_pointer_type ptr) const
{
#ifdef USE64
uintptr_t p = reinterpret_cast<uintptr_t>(ptr);
if ((p & ALIGNMENT_MASK) != 0) {
//throw bad_alignment("Pointer is not aligned");
exit(-1);
}
return (uint32_t)(ptr2seg(p) + p);
#else // 32 bit machine
return reinterpret_cast<uint32_t>(ptr);
#endif
}
inline native_pointer_type decode(uint32_t e) const
{
#ifdef USE64
uintptr_t el = e;
uintptr_t ptr = (_seg_map[el & ALIGNMENT_MASK] + el) & ~ALIGNMENT_MASK;
return reinterpret_cast<native_pointer_type>(ptr);
#else
return reinterpret_cast<native_pointer_type>(e);
#endif
}
void check_alignment() const
{
//BOOST_STATIC_ASSERT(is_n_aligned(TYPE, ALIGNMENT));
}
void inc_sptr(uint32_t& e, uintptr_t offset = 1)
{
check_alignment();
#ifdef USE64
uintptr_t el = e;
uintptr_t seg = el & ALIGNMENT_MASK;
el += offset*ALIGNMENT;
// check for overflow
if (el > 0xFFFFFFFFULL)
return encode(decode(e)+1);
e = (uint32_t)el;
#else
e+= (uint32_t)offset;
#endif
}
void dec_sptr(uint32_t& e, size_t offset = 1)
{
check_alignment();
#ifdef USE64
uintptr_t el = e;
// uintptr_t seg = el & ALIGNMENT_MASK;
e-= offset*ALIGNMENT;
// check for underflow
if (el > 0xFFFFFFFFULL)
return encode(decode(e)-1);
e = (uint32_t)el;
#else
e -= (uint32_t)offset;
#endif
}
public:
TYPE* get() const throw() { return decode(_ptr); }
// Pointer operators
TYPE& operator*() { return *decode(_ptr); }
const TYPE& operator*() const { return *decode(_ptr); }
TYPE* operator->() { return decode(_ptr); }
const TYPE* operator->() const { return decode(_ptr); }
template<class O>
bool operator==(const sptr<O>& o) const
{
return o._ptr == this->_ptr;
}
operator TYPE*() const { return get(); }
sptr<TYPE>& operator++( )
{
inc_sptr(_ptr);
return *this;
}
sptr<TYPE> operator++( int )
{
sptr<TYPE> p = *this;
inc_sptr(_ptr);
return p;
}
sptr<TYPE>& operator--( )
{
dec_sptr(_ptr);
return *this;
}
sptr<TYPE> operator--( int )
{
sptr<TYPE> p = *this;
dec_sptr(_ptr);
return p;
}
sptr<TYPE>& operator+=(size_t offset)
{
inc_sptr(_ptr, offset);
return *this;
}
sptr<TYPE>& operator-=(size_t offset)
{
dec_sptr(_ptr, offset);
return *this;
}
private:
uint32_t _ptr;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,740 @@
/****************************************************************************************[Solver.h]
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
glucose -- Gilles Audemard, Laurent Simon (2008)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#ifndef SOLVER_H
#define SOLVER_H
#include <cstdio>
#include <string.h>
#include <stdio.h>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "Vec.h"
#include "Heap.h"
#include "Alg.h"
#include "MersenneTwister.h"
#include "SolverTypes.h"
#include "Clause.h"
#include "constants.h"
#include "BoundedQueue.h"
#ifdef STATS_NEEDED
#include "Logger.h"
#endif //STATS_NEEDED
#ifdef USE_GAUSS
#include "GaussianConfig.h"
#endif //USE_GAUSS
#ifdef USE_GAUSS
class Gaussian;
class MatrixFinder;
#endif //USE_GAUSS
class Conglomerate;
class VarReplacer;
class XorFinder;
class FindUndef;
class ClauseCleaner;
class FailedVarSearcher;
class Subsumer;
class XorSubsumer;
class PartHandler;
class RestartTypeChooser;
class StateSaver;
#ifdef VERBOSE_DEBUG
#define DEBUG_UNCHECKEDENQUEUE_LEVEL0
using std::cout;
using std::endl;
#endif
//=================================================================================================
// Solver -- the main class:
struct reduceDB_ltMiniSat
{
bool operator () (const Clause* x, const Clause* y);
};
struct reduceDB_ltGlucose
{
bool operator () (const Clause* x, const Clause* y);
};
class Solver
{
public:
// Constructor/Destructor:
//
Solver();
~Solver();
// Problem specification:
//
Var newVar (bool dvar = true); // Add a new variable with parameters specifying variable mode.
template<class T>
bool addClause (T& ps, const uint group = 0, char* group_name = NULL); // Add a clause to the solver. NOTE! 'ps' may be shrunk by this method!
template<class T>
bool addXorClause (T& ps, bool xor_clause_inverted, const uint group = 0, char* group_name = NULL); // Add a xor-clause to the solver. NOTE! 'ps' may be shrunk by this method!
// Solving:
//
lbool solve (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions.
lbool solve (); // Search without assumptions.
bool okay () const; // FALSE means solver is in a conflicting state
// Variable mode:
//
void setPolarity (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'.
void setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic.
void setSeed (const uint32_t seed); // Sets the seed to be the given number
void setMaxRestarts(const uint num); //sets the maximum number of restarts to given value
// Read state:
//
lbool value (const Var& x) const; // The current value of a variable.
lbool value (const Lit& p) const; // The current value of a literal.
lbool modelValue (const Lit& p) const; // The value of a literal in the last model. The last call to solve must have been satisfiable.
uint32_t nAssigns () const; // The current number of assigned literals.
uint32_t nClauses () const; // The current number of original clauses.
uint32_t nLiterals () const; // The current number of total literals.
uint32_t nLearnts () const; // The current number of learnt clauses.
uint32_t nVars () const; // The current number of variables.
// Extra results: (read-only member variable)
//
vec<lbool> model; // If problem is satisfiable, this vector contains the model (if any).
vec<Lit> conflict; // If problem is unsatisfiable (possibly under assumptions),
// this vector represent the final conflict clause expressed in the assumptions.
// Mode of operation:
//
double random_var_freq; // The frequency with which the decision heuristic tries to choose a random variable. (default 0.02)
double clause_decay; // Inverse of the clause activity decay factor. (1 / 0.999)
int restart_first; // The initial restart limit. (default 100)
double restart_inc; // The factor with which the restart limit is multiplied in each restart. (default 1.5)
double learntsize_factor; // The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3)
double learntsize_inc; // The limit for learnt clauses is multiplied with this factor each restart. (default 1.1)
bool expensive_ccmin; // Controls conflict clause minimization. (default TRUE)
int polarity_mode; // Controls which polarity the decision heuristic chooses. See enum below for allowed modes. (default polarity_false)
int verbosity; // Verbosity level. 0=silent, 1=some progress report (default 0)
Var restrictedPickBranch; // Pick variables to branch on preferentally from the highest [0, restrictedPickBranch]. If set to 0, preferentiality is turned off (i.e. picked randomly between [0, all])
bool findNormalXors; // Automatically find non-binary xor-clauses and convert them
bool findBinaryXors; // Automatically find binary xor-clauses and convert them
bool regularlyFindBinaryXors; // Regularly find binary xor-clauses and convert them
bool performReplace; // Should var-replacing be performed?
bool conglomerateXors; // Conglomerate XORs
bool heuleProcess; // Process XORs according to Heule
bool schedSimplification;// Schedule simplification
bool doSubsumption; // Should try to subsume clauses
bool doXorSubsumption; // Should try to subsume xor clauses
bool doPartHandler; // Should try to subsume clauses
bool doHyperBinRes; // Should try carry out hyper-binary resolution
bool doBlockedClause; // Should try to remove blocked clauses
bool doVarElim; // Perform variable elimination
bool doSubsume1; // Perform clause contraction through resolution
bool failedVarSearch; // Should search for failed vars and doulbly propagated vars
bool readdOldLearnts; // Should re-add old learnts for failed variable searching
bool addExtraBins; // Should add extra binaries in failed literal probing
bool removeUselessBins; // Should try to remove useless binary clauses
bool regularRemoveUselessBins; // Should try to remove useless binary clauses regularly
bool subsumeWithNonExistBinaries;
bool regularSubsumeWithNonExistBinaries;
bool libraryUsage; // Set true if not used as a library
friend class FindUndef;
bool greedyUnbound; //If set, then variables will be greedily unbounded (set to l_Undef)
RestartType fixRestartType; // If set, the solver will always choose the given restart strategy
#ifdef USE_GAUSS
GaussianConfig gaussconfig;
#endif //USE_GAUSS
enum { polarity_true = 0, polarity_false = 1, polarity_rnd = 3, polarity_auto = 4};
// Statistics: (read-only member variable)
//
uint64_t starts, dynStarts, staticStarts, fullStarts, decisions, rnd_decisions, propagations, conflicts;
uint64_t clauses_literals, learnts_literals, max_literals, tot_literals;
uint64_t nbDL2, nbBin, lastNbBin, becameBinary, lastSearchForBinaryXor, nbReduceDB;
uint64_t improvedClauseNo, improvedClauseSize;
//Logging
void needStats(); // Prepares the solver to output statistics
void needProofGraph(); // Prepares the solver to output proof graphs during solving
void setVariableName(Var var, char* name); // Sets the name of the variable 'var' to 'name'. Useful for statistics and proof logs (i.e. used by 'logger')
const vec<Clause*>& get_sorted_learnts(); //return the set of learned clauses, sorted according to the logic used in MiniSat to distinguish between 'good' and 'bad' clauses
const vec<Clause*>& get_learnts() const; //Get all learnt clauses that are >1 long
const vector<Lit> get_unitary_learnts() const; //return the set of unitary learnt clauses
const uint get_unitary_learnts_num() const; //return the number of unitary learnt clauses
void dumpSortedLearnts(const char* file, const uint32_t maxSize); // Dumps all learnt clauses (including unitary ones) into the file
void needLibraryCNFFile(const char* fileName); //creates file in current directory with the filename indicated, and puts all calls from the library into the file.
#ifdef USE_GAUSS
const uint32_t get_sum_gauss_called() const;
const uint32_t get_sum_gauss_confl() const;
const uint32_t get_sum_gauss_prop() const;
const uint32_t get_sum_gauss_unit_truths() const;
#endif //USE_GAUSS
//Printing statistics
const uint32_t getNumElimSubsume() const; // Get variable elimination stats from Subsumer
const uint32_t getNumElimXorSubsume() const; // Get variable elimination stats from XorSubsumer
const uint32_t getNumXorTrees() const; // Get the number of trees built from 2-long XOR-s. This is effectively the number of variables that replace other variables
const uint32_t getNumXorTreesCrownSize() const; // Get the number of variables being replaced by other variables
const double getTotalTimeSubsumer() const;
const double getTotalTimeXorSubsumer() const;
protected:
#ifdef USE_GAUSS
void print_gauss_sum_stats();
void clearGaussMatrixes();
vector<Gaussian*> gauss_matrixes;
//stats
uint32_t sum_gauss_called;
uint32_t sum_gauss_confl;
uint32_t sum_gauss_prop;
uint32_t sum_gauss_unit_truths;
friend class Gaussian;
#endif //USE_GAUSS
template <class T>
Clause* addClauseInt(T& ps, uint group);
template<class T>
XorClause* addXorClauseInt(T& ps, bool xor_clause_inverted, const uint32_t group);
template<class T>
bool addLearntClause(T& ps, const uint group, const uint32_t activity);
template<class T>
void removeWatchedCl(vec<T> &ws, const Clause *c);
template<class T>
bool findWatchedCl(const vec<T>& ws, const Clause *c) const;
template<class T>
void removeWatchedBinCl(vec<T> &ws, const Clause *c);
template<class T>
bool findWatchedBinCl(const vec<T>& ws, const Clause *c) const;
// Helper structures:
//
struct VarOrderLt {
const vec<uint32_t>& activity;
bool operator () (Var x, Var y) const {
return activity[x] > activity[y];
}
VarOrderLt(const vec<uint32_t>& act) : activity(act) { }
};
friend class VarFilter;
struct VarFilter {
const Solver& s;
VarFilter(const Solver& _s) : s(_s) {}
bool operator()(Var v) const {
return s.assigns[v].isUndef() && s.decision_var[v];
}
};
// Solver state:
//
bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
vec<Clause*> clauses; // List of problem clauses.
vec<Clause*> binaryClauses; // Binary clauses are regularly moved here
vec<XorClause*> xorclauses; // List of problem xor-clauses. Will be freed
vec<Clause*> learnts; // List of learnt clauses.
vec<Clause*> removedLearnts; // Clauses that have been learnt, then removed
vec<XorClause*> freeLater; // xor clauses that need to be freed later due to Gauss
vec<uint32_t> activity; // A heuristic measurement of the activity of a variable.
uint32_t var_inc; // Amount to bump next variable with.
double cla_inc; // Amount to bump learnt clause oldActivity with
vec<vec<Watched> > watches; // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
vec<vec<XorClausePtr> > xorwatches; // 'xorwatches[var]' is a list of constraints watching var in XOR clauses.
vec<vec<WatchedBin> > binwatches;
vec<lbool> assigns; // The current assignments
vector<bool> polarity; // The preferred polarity of each variable.
#ifdef USE_OLD_POLARITIES
vector<bool> oldPolarity; // The polarity before the last setting. Good for unsetting polairties that have been changed since the last conflict
#endif //USE_OLD_POLARITIES
vector<bool> decision_var; // Declares if a variable is eligible for selection in the decision heuristic.
vec<Lit> trail; // Assignment stack; stores all assigments made in the order they were made.
vec<uint32_t> trail_lim; // Separator indices for different decision levels in 'trail'.
vec<ClausePtr> reason; // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
vec<int32_t> level; // 'level[var]' contains the level at which the assignment was made.
uint64_t curRestart;
uint32_t nbclausesbeforereduce;
uint32_t nbCompensateSubsumer; // Number of learnt clauses that subsumed normal clauses last time subs. was executed
uint32_t qhead; // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
uint32_t simpDB_assigns; // Number of top-level assignments since last execution of 'simplify()'.
int64_t simpDB_props; // Remaining number of propagations that must be made before next execution of 'simplify()'.
vec<Lit> assumptions; // Current set of assumptions provided to solve by the user.
Heap<VarOrderLt> order_heap; // A priority queue of variables ordered with respect to the variable activity.
double progress_estimate;// Set by 'search()'.
bool remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'.
bqueue<uint> nbDecisionLevelHistory; // Set of last decision level in conflict clauses
double totalSumOfDecisionLevel;
uint64_t conflictsAtLastSolve;
#ifdef RANDOM_LOOKAROUND_SEARCHSPACE
bqueue<uint> avgBranchDepth; // Avg branch depth
#endif //RANDOM_LOOKAROUND_SEARCHSPACE
MTRand mtrand; // random number generaton
RestartType restartType; // Used internally to determine which restart strategy to choose
RestartType lastSelectedRestartType; //the last selected restart type
friend class Logger;
#ifdef STATS_NEEDED
Logger logger; // dynamic logging, statistics
bool dynamic_behaviour_analysis; // Is logger running?
#endif
uint maxRestarts; // More than this number of restarts will not be performed
// Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
// used, exept 'seen' wich is used in several places.
//
vector<bool> seen;
vec<Lit> analyze_stack;
vec<Lit> analyze_toclear;
vec<Lit> add_tmp;
uint64_t MYFLAG;
template<class T>
const uint32_t calcNBLevels(const T& ps);
vec<uint64_t> permDiff; // LS: permDiff[var] contains the current conflict number... Used to count the number of different decision level variables in learnt clause
#ifdef UPDATEVARACTIVITY
vec<Var> lastDecisionLevel;
#endif
//Logging
uint learnt_clause_group; //the group number of learnt clauses. Incremented at each added learnt clause
FILE *libraryCNFFile; //The file that all calls from the library are logged
// Main internal methods:
//
const bool simplify (); // Removes already satisfied clauses.
//int nbPropagated (int level);
void insertVarOrder (Var x); // Insert a variable in the decision order priority queue.
Lit pickBranchLit (); // Return the next decision variable.
void newDecisionLevel (); // Begins a new decision level.
void uncheckedEnqueue (Lit p, ClausePtr from = (Clause*)NULL); // Enqueue a literal. Assumes value of literal is undefined.
void uncheckedEnqueueLight (const Lit p);
bool enqueue (Lit p, Clause* from = NULL); // Test if fact 'p' contradicts current state, enqueue otherwise.
Clause* propagate (const bool update = true); // Perform unit propagation. Returns possibly conflicting clause.
Clause* propagateLight();
Clause* propagateBin();
Clause* propagateBinNoLearnts();
template<bool dontCareLearnt>
Clause* propagateBinExcept(const Lit& exceptLit);
template<bool dontCareLearnt>
Clause* propagateBinOneLevel();
Clause* propagate_xors (const Lit& p);
void cancelUntil (int level); // Backtrack until a certain level.
Clause* analyze (Clause* confl, vec<Lit>& out_learnt, int& out_btlevel, uint32_t &nblevels, const bool update); // (bt = backtrack)
void analyzeFinal (Lit p, vec<Lit>& out_conflict); // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION?
bool litRedundant (Lit p, uint32_t abstract_levels); // (helper method for 'analyze()')
lbool search (int nof_conflicts, int nof_conflicts_fullrestart, const bool update = true); // Search for a given number of conflicts.
void reduceDB (); // Reduce the set of learnt clauses.
llbool handle_conflict (vec<Lit>& learnt_clause, Clause* confl, int& conflictC, const bool update);// Handles the conflict clause
llbool new_decision (const int& nof_conflicts, const int& nof_conflicts_fullrestart, int& conflictC); // Handles the case when all propagations have been made, and now a decision must be made
// Maintaining Variable/Clause activity:
//
void claBumpActivity (Clause& c);
void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead.
void varBumpActivity (Var v); // Increase a variable with the current 'bump' value.
void claDecayActivity (); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead.
// Operations on clauses:
//
void attachClause (XorClause& c);
void attachClause (Clause& c); // Attach a clause to watcher lists.
void detachClause (const XorClause& c);
void detachClause (const Clause& c); // Detach a clause to watcher lists.
void detachModifiedClause(const Lit lit1, const Lit lit2, const uint size, const Clause* address);
void detachModifiedClause(const Var var1, const Var var2, const uint origSize, const XorClause* address);
template<class T>
void removeClause(T& c); // Detach and free a clause.
bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state.
void reverse_binary_clause(Clause& c) const; // Binary clauses --- the first Lit has to be true
void testAllClauseAttach() const;
void findAllAttach() const;
const bool findClause(XorClause* c) const;
const bool findClause(Clause* c) const;
// Misc:
//
uint32_t decisionLevel () const; // Gives the current decisionlevel.
uint32_t abstractLevel (const Var& x) const; // Used to represent an abstraction of sets of decision levels.
//Xor-finding related stuff
friend class XorFinder;
friend class Conglomerate;
friend class MatrixFinder;
friend class PartFinder;
friend class VarReplacer;
friend class ClauseCleaner;
friend class RestartTypeChooser;
friend class FailedVarSearcher;
friend class Subsumer;
friend class XorSubsumer;
friend class PartHandler;
friend class StateSaver;
Conglomerate* conglomerate;
VarReplacer* varReplacer;
ClauseCleaner* clauseCleaner;
FailedVarSearcher* failedVarSearcher;
PartHandler* partHandler;
Subsumer* subsumer;
XorSubsumer* xorSubsumer;
RestartTypeChooser* restartTypeChooser;
MatrixFinder* matrixFinder;
const bool chooseRestartType(const uint& lastFullRestart);
void setDefaultRestartType();
const bool checkFullRestart(int& nof_conflicts, int& nof_conflicts_fullrestart, uint& lastFullRestart);
void performStepsBeforeSolve();
const lbool simplifyProblem(const uint32_t numConfls);
bool simplifying;
// Debug & etc:
void printLit (const Lit l) const;
void verifyModel ();
bool verifyClauses (const vec<Clause*>& cs) const;
bool verifyXorClauses (const vec<XorClause*>& cs) const;
void checkSolution();
void checkLiteralCount();
void printStatHeader () const;
void printRestartStat ();
void printEndSearchStat();
double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
const bool noLearntBinaries() const;
// Polarity chooser
void calculateDefaultPolarities(); //Calculates the default polarity for each var, and fills defaultPolarities[] with it
bool defaultPolarity(); //if polarity_mode is not polarity_auto, this returns the default polarity of the variable
void tallyVotes(const vec<Clause*>& cs, vector<double>& votes) const;
void tallyVotes(const vec<XorClause*>& cs, vector<double>& votes) const;
};
//=================================================================================================
// Implementation of inline methods:
inline void Solver::insertVarOrder(Var x)
{
if (!order_heap.inHeap(x) && decision_var[x]) order_heap.insert(x);
}
inline void Solver::varDecayActivity()
{
var_inc *= 11;
var_inc /= 10;
}
inline void Solver::varBumpActivity(Var v)
{
if ( (activity[v] += var_inc) > (0x1U) << 24 ) {
//printf("RESCALE!!!!!!\n");
//std::cout << "var_inc: " << var_inc << std::endl;
// Rescale:
for (Var var = 0; var != nVars(); var++) {
activity[var] >>= 14;
}
var_inc >>= 14;
//var_inc = 1;
//std::cout << "var_inc: " << var_inc << std::endl;
/*Heap<VarOrderLt> copy_order_heap2(order_heap);
while(!copy_order_heap2.empty()) {
Var v = copy_order_heap2.getmin();
if (decision_var[v])
std::cout << "var_" << v+1 << " act: " << activity[v] << std::endl;
}*/
}
// Update order_heap with respect to new activity:
if (order_heap.inHeap(v))
order_heap.decrease(v);
}
inline void Solver::claBumpActivity (Clause& c)
{
if ( (c.oldActivity() += cla_inc) > 1e20 ) {
// Rescale:
for (uint32_t i = 0; i < learnts.size(); i++)
learnts[i]->oldActivity() *= 1e-17;
cla_inc *= 1e-20;
}
}
inline void Solver::claDecayActivity()
{
//cla_inc *= clause_decay;
}
inline bool Solver::enqueue (Lit p, Clause* from)
{
return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true);
}
inline bool Solver::locked (const Clause& c) const
{
return reason[c[0].var()] == &c && value(c[0]) == l_True;
}
inline void Solver::newDecisionLevel()
{
trail_lim.push(trail.size());
#ifdef VERBOSE_DEBUG
cout << "New decision level: " << trail_lim.size() << endl;
#endif
}
/*inline int Solver::nbPropagated(int level) {
if (level == decisionLevel())
return trail.size() - trail_lim[level-1] - 1;
return trail_lim[level] - trail_lim[level-1] - 1;
}*/
inline uint32_t Solver::decisionLevel () const
{
return trail_lim.size();
}
inline uint32_t Solver::abstractLevel (const Var& x) const
{
return 1 << (level[x] & 31);
}
inline lbool Solver::value (const Var& x) const
{
return assigns[x];
}
inline lbool Solver::value (const Lit& p) const
{
return assigns[p.var()] ^ p.sign();
}
inline lbool Solver::modelValue (const Lit& p) const
{
return model[p.var()] ^ p.sign();
}
inline uint32_t Solver::nAssigns () const
{
return trail.size();
}
inline uint32_t Solver::nClauses () const
{
return clauses.size() + xorclauses.size()+binaryClauses.size();
}
inline uint32_t Solver::nLiterals () const
{
return clauses_literals + learnts_literals;
}
inline uint32_t Solver::nLearnts () const
{
return learnts.size();
}
inline uint32_t Solver::nVars () const
{
return assigns.size();
}
inline void Solver::setPolarity (Var v, bool b)
{
polarity [v] = (char)b;
}
inline void Solver::setDecisionVar(Var v, bool b)
{
decision_var[v] = b;
if (b) {
insertVarOrder(v);
}
}
inline lbool Solver::solve ()
{
vec<Lit> tmp;
return solve(tmp);
}
inline bool Solver::okay () const
{
return ok;
}
inline void Solver::setSeed (const uint32_t seed)
{
mtrand.seed(seed); // Set seed of the variable-selection and clause-permutation(if applicable)
}
#ifdef STATS_NEEDED
inline void Solver::needStats()
{
dynamic_behaviour_analysis = true; // Sets the solver and the logger up to generate statistics
logger.statistics_on = true;
}
inline void Solver::needProofGraph()
{
dynamic_behaviour_analysis = true; // Sets the solver and the logger up to generate proof graphs during solving
logger.proof_graph_on = true;
}
inline void Solver::setVariableName(Var var, char* name)
{
while (var >= nVars()) newVar();
if (dynamic_behaviour_analysis)
logger.set_variable_name(var, name);
} // Sets the varible 'var'-s name to 'name' in the logger
#else
inline void Solver::setVariableName(Var var, char* name)
{}
#endif
#ifdef USE_GAUSS
inline const uint32_t Solver::get_sum_gauss_unit_truths() const
{
return sum_gauss_unit_truths;
}
inline const uint32_t Solver::get_sum_gauss_called() const
{
return sum_gauss_called;
}
inline const uint32_t Solver::get_sum_gauss_confl() const
{
return sum_gauss_confl;
}
inline const uint32_t Solver::get_sum_gauss_prop() const
{
return sum_gauss_prop;
}
#endif
inline const uint Solver::get_unitary_learnts_num() const
{
if (decisionLevel() > 0)
return trail_lim[0];
else
return trail.size();
}
template <class T>
inline void Solver::removeWatchedCl(vec<T> &ws, const Clause *c) {
uint32_t j = 0;
for (; j < ws.size() && ws[j].clause != c; j++);
assert(j < ws.size());
for (; j < ws.size()-1; j++) ws[j] = ws[j+1];
ws.pop();
}
template <class T>
inline void Solver::removeWatchedBinCl(vec<T> &ws, const Clause *c) {
uint32_t j = 0;
for (; j < ws.size() && ws[j].clause != c; j++);
assert(j < ws.size());
for (; j < ws.size()-1; j++) ws[j] = ws[j+1];
ws.pop();
}
template<class T>
inline bool Solver::findWatchedCl(const vec<T>& ws, const Clause *c) const
{
uint32_t j = 0;
for (; j < ws.size() && ws[j].clause != c; j++);
return j < ws.size();
}
template<class T>
inline bool Solver::findWatchedBinCl(const vec<T>& ws, const Clause *c) const
{
uint32_t j = 0;
for (; j < ws.size() && ws[j].clause != c; j++);
return j < ws.size();
}
inline void Solver::reverse_binary_clause(Clause& c) const {
if (c.size() == 2 && value(c[0]) == l_False) {
assert(value(c[1]) == l_True);
std::swap(c[0], c[1]);
}
}
/*inline void Solver::calculate_xor_clause(Clause& c2) const {
if (c2.isXor() && ((XorClause*)&c2)->updateNeeded()) {
XorClause& c = *((XorClause*)&c2);
bool final = c.xor_clause_inverted();
for (int k = 0, size = c.size(); k != size; k++ ) {
const lbool& val = assigns[c[k].var()];
assert(val != l_Undef);
c[k] = c[k].unsign() ^ val.getBool();
final ^= val.getBool();
}
if (final)
c[0] = c[0].unsign() ^ !assigns[c[0].var()].getBool();
c.setUpdateNeeded(false);
}
}*/
template<class T>
inline void Solver::removeClause(T& c)
{
detachClause(c);
clauseFree(&c);
}
//=================================================================================================
// Debug + etc:
static inline void logLit(FILE* f, Lit l)
{
fprintf(f, "%sx%d", l.sign() ? "~" : "", l.var()+1);
}
static inline void logLits(FILE* f, const vec<Lit>& ls)
{
fprintf(f, "[ ");
if (ls.size() > 0) {
logLit(f, ls[0]);
for (uint32_t i = 1; i < ls.size(); i++) {
fprintf(f, ", ");
logLit(f, ls[i]);
}
}
fprintf(f, "] ");
}
static inline const char* showBool(bool b)
{
return b ? "true" : "false";
}
// Just like 'assert()' but expression will be evaluated in the release version as well.
static inline void check(bool expr)
{
assert(expr);
}
#ifndef DEBUG_ATTACH
inline void Solver::testAllClauseAttach() const
{
return;
}
inline void Solver::findAllAttach() const
{
return;
}
#endif //DEBUG_ATTACH
inline void Solver::uncheckedEnqueueLight(const Lit p)
{
assigns [p.var()] = boolToLBool(!p.sign());//lbool(!sign(p)); // <<== abstract but not uttermost effecient
trail.push(p);
}
//=================================================================================================
#endif //SOLVER_H

View File

@ -0,0 +1,179 @@
/***********************************************************************************[SolverTypes.h]
MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#ifndef SOLVERTYPES_H
#define SOLVERTYPES_H
#include <cassert>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include "Alg.h"
#include <stdio.h>
//=================================================================================================
// Variables, literals, lifted booleans, clauses:
// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
// so that they can be used as array indices.
typedef uint32_t Var;
#define var_Undef (0xffffffffU >>1)
enum RestartType {dynamic_restart, static_restart, auto_restart};
class Lit
{
uint32_t x;
explicit Lit(uint32_t i) : x(i) { };
public:
Lit() : x(2*var_Undef) {} // (lit_Undef)
explicit Lit(Var var, bool sign) : x((var+var) + (int)sign) { }
const uint32_t& toInt() const { // Guarantees small, positive integers suitable for array indexing.
return x;
}
Lit operator~() const {
return Lit(x ^ 1);
}
Lit operator^(const bool b) const {
return Lit(x ^ (uint32_t)b);
}
Lit& operator^=(const bool b) {
x ^= (uint32_t)b;
return *this;
}
bool sign() const {
return x & 1;
}
Var var() const {
return x >> 1;
}
Lit unsign() const {
return Lit(x & ~1);
}
bool operator==(const Lit& p) const {
return x == p.x;
}
bool operator!= (const Lit& p) const {
return x != p.x;
}
bool operator < (const Lit& p) const {
return x < p.x; // '<' guarantees that p, ~p are adjacent in the ordering.
}
inline void print(FILE* outfile = stdout) const
{
fprintf(outfile,"%s%d", sign() ? "-" : "", var()+1);
}
inline void printFull(FILE* outfile = stdout) const
{
fprintf(outfile,"%s%d 0\n", sign() ? "-" : "", var()+1);
}
};
const Lit lit_Undef(var_Undef, false); // Useful special constants.
const Lit lit_Error(var_Undef, true ); //
//=================================================================================================
// Lifted booleans:
class llbool;
class lbool
{
char value;
explicit lbool(char v) : value(v) { }
public:
lbool() : value(0) { };
inline char getchar() const {
return value;
}
inline lbool(llbool b);
inline const bool isUndef() const {
return !value;
}
inline const bool isDef() const {
return value;
}
inline const bool getBool() const {
return value == 1;
}
inline const bool operator==(lbool b) const {
return value == b.value;
}
inline const bool operator!=(lbool b) const {
return value != b.value;
}
lbool operator^(const bool b) const {
return b ? lbool(-value) : lbool(value);
}
//lbool operator ^ (const bool b) const { return b ? lbool(-value) : lbool(value); }
friend lbool toLbool(const char v);
friend lbool boolToLBool(const bool b);
friend class llbool;
};
inline lbool toLbool(const char v)
{
return lbool(v);
}
inline lbool boolToLBool(const bool b)
{
return lbool(2*b-1);
}
const lbool l_True = toLbool( 1);
const lbool l_False = toLbool(-1);
const lbool l_Undef = toLbool( 0);
class llbool
{
char value;
public:
llbool(): value(0) {};
llbool(lbool v) :
value(v.value) {};
llbool(char a) :
value(a) {}
inline const bool operator!=(const llbool& v) const {
return (v.value != value);
}
inline const bool operator==(const llbool& v) const {
return (v.value == value);
}
friend class lbool;
};
const llbool l_Nothing = toLbool(2);
const llbool l_Continue = toLbool(3);
lbool::lbool(llbool b) : value(b.value) {};
#endif //SOLVERTYPES_H

View File

@ -0,0 +1,48 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "StateSaver.h"
StateSaver::StateSaver(Solver& _solver) :
solver(_solver)
, backup_order_heap(Solver::VarOrderLt(solver.activity))
{
//Saving Solver state
backup_var_inc = solver.var_inc;
backup_activity.growTo(solver.activity.size());
std::copy(solver.activity.getData(), solver.activity.getDataEnd(), backup_activity.getData());
backup_order_heap = solver.order_heap;
backup_polarities = solver.polarity;
backup_restartType = solver.restartType;
backup_random_var_freq = solver.random_var_freq;
backup_propagations = solver.propagations;
}
void StateSaver::restore()
{
//Restore Solver state
solver.var_inc = backup_var_inc;
std::copy(backup_activity.getData(), backup_activity.getDataEnd(), solver.activity.getData());
solver.order_heap = backup_order_heap;
solver.polarity = backup_polarities;
solver.restartType = backup_restartType;
solver.random_var_freq = backup_random_var_freq;
//Finally, clear the order_heap from variables set/non-decisionned
solver.order_heap.filter(Solver::VarFilter(solver));
solver.propagations = backup_propagations;
}

View File

@ -0,0 +1,40 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef STATESAVER__H
#define STATESAVER__H
#include "Solver.h"
class StateSaver
{
public:
StateSaver(Solver& _solver);
void restore();
private:
Solver& solver;
Heap<Solver::VarOrderLt> backup_order_heap;
vector<bool> backup_polarities;
vec<uint32_t> backup_activity;
uint32_t backup_var_inc;
RestartType backup_restartType;
uint32_t backup_random_var_freq;
uint64_t backup_propagations;
};
#endif //STATESAVER__H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,275 @@
/**************************************************************************************************
Originally From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
Substantially modified by: Mate Soos (2010)
**************************************************************************************************/
#ifndef SIMPLIFIER_H
#define SIMPLIFIER_H
#include "Solver.h"
#include "Queue.h"
#include "CSet.h"
#include "BitArray.h"
#include <map>
#include <vector>
#include <queue>
using std::vector;
using std::map;
using std::priority_queue;
class ClauseCleaner;
class Subsumer
{
public:
//Construct-destruct
Subsumer(Solver& S2);
~Subsumer();
//Called from main
const bool simplifyBySubsumption();
const bool subsumeWithBinaries(const bool startUp);
void newVar();
//Used by cleaner
void unlinkModifiedClause(vec<Lit>& origClause, ClauseSimp c);
void unlinkModifiedClauseNoDetachNoNULL(vec<Lit>& origClause, ClauseSimp c);
void unlinkClause(ClauseSimp cc, Var elim = var_Undef);
ClauseSimp linkInClause(Clause& cl);
void linkInAlreadyClause(ClauseSimp& c);
void updateClause(ClauseSimp c);
//UnElimination
void extendModel(Solver& solver2);
const bool unEliminate(const Var var);
//Get-functions
const vec<char>& getVarElimed() const;
const uint32_t getNumElimed() const;
const bool checkElimedUnassigned() const;
const double getTotalTime() const;
private:
friend class ClauseCleaner;
//Main
vec<ClauseSimp> clauses;
CSet learntClauses;
vec<char> touched; // Is set to true when a variable is part of a removed clause. Also true initially (upon variable creation).
vec<Var> touched_list; // A list of the true elements in 'touched'.
CSet cl_touched; // Clauses strengthened.
CSet cl_added; // Clauses created.
vec<vec<ClauseSimp> > occur; // 'occur[index(lit)]' is a list of constraints containing 'lit'.
vec<vec<ClauseSimp>* > iter_vecs; // Vectors currently used for iterations. Removed clauses will be looked up and replaced by 'Clause_NULL'.
vec<CSet* > iter_sets; // Sets currently used for iterations.
vec<char> cannot_eliminate;//
//Global stats
Solver& solver;
vec<char> var_elimed; //TRUE if var has been eliminated
double totalTime;
uint32_t numElimed;
map<Var, vector<Clause*> > elimedOutVar;
// Temporaries (to reduce allocation overhead):
//
vec<char> seen_tmp; // (used in various places)
//Limits
uint32_t numVarsElimed;
uint32_t numMaxSubsume1;
uint32_t numMaxSubsume0;
uint32_t numMaxElim;
int64_t numMaxBlockToVisit;
uint32_t numMaxBlockVars;
//Start-up
template<bool UseCL>
void addFromSolver(vec<Clause*>& cs, bool alsoLearnt = false);
void addBackToSolver();
void removeWrong(vec<Clause*>& cs);
void removeAssignedVarsFromEliminated();
void fillCannotEliminate();
const bool treatLearnts();
void clearAll();
//Iterations
void registerIteration (CSet& iter_set) { iter_sets.push(&iter_set); }
void unregisterIteration(CSet& iter_set) { remove(iter_sets, &iter_set); }
void registerIteration (vec<ClauseSimp>& iter_vec) { iter_vecs.push(&iter_vec); }
void unregisterIteration(vec<ClauseSimp>& iter_vec) { remove(iter_vecs, &iter_vec); }
// Subsumption:
void touch(const Var x);
void touch(const Lit p);
template<class T>
void findSubsumed(const T& ps, const uint32_t abst, vec<ClauseSimp>& out_subsumed);
bool isSubsumed(Clause& ps);
template<class T>
uint32_t subsume0(T& ps, uint32_t abs);
template<class T>
uint32_t subsume0Orig(const T& ps, uint32_t abs);
void subsume0BIN(const Lit lit, const vec<char>& lits);
void subsume0LearntSet(vec<Clause*>& cs);
void subsume1(ClauseSimp& ps);
void smaller_database();
void almost_all_database();
template<class T1, class T2>
bool subset(const T1& A, const T2& B);
bool subsetAbst(uint32_t A, uint32_t B);
void orderVarsForElim(vec<Var>& order);
int substitute(Lit x, Clause& def, vec<Clause*>& poss, vec<Clause*>& negs, vec<Clause*>& new_clauses);
bool maybeEliminate(Var x);
void MigrateToPsNs(vec<ClauseSimp>& poss, vec<ClauseSimp>& negs, vec<ClauseSimp>& ps, vec<ClauseSimp>& ns, const Var x);
void DeallocPsNs(vec<ClauseSimp>& ps, vec<ClauseSimp>& ns);
bool merge(const Clause& ps, const Clause& qs, const Lit without_p, const Lit without_q, vec<Lit>& out_clause);
//Subsume with Nonexistent Bins
const bool subsWNonExistBinsFull(const bool startUp);
const bool subsWNonExistBins(const Lit& lit, const bool startUp);
template<class T>
void subsume1Partial(const T& ps);
uint32_t subsNonExistentNum;
uint32_t subsNonExistentumFailed;
bool subsNonExistentFinish;
double subsNonExistentTime;
uint32_t subsNonExistentLitsRemoved;
vec<Clause*> addBinaryClauses;
uint32_t doneNum;
vec<ClauseSimp> subsume1PartialSubs;
vec<Lit> subsume1PartialQs;
vec<Lit> toVisit;
vec<char> toVisitAll;
vec<Lit> ps2;
//hyperBinRes
void addFromSolverAll(vec<Clause*>& cs);
const bool hyperBinRes();
const bool hyperUtility(vec<ClauseSimp>& iter, const Lit lit, BitArray& inside, vec<Clause*>& addToClauses);
//merging
//vector<char> merge();
//const bool checkIfSame(const Lit var1, const Lit var2);
class VarOcc {
public:
VarOcc(const Var& v, const uint32_t num) :
var(v)
, occurnum(num)
{}
Var var;
uint32_t occurnum;
};
struct MyComp {
const bool operator() (const VarOcc& l1, const VarOcc& l2) const {
return l1.occurnum > l2.occurnum;
}
};
void blockedClauseRemoval();
const bool allTautology(const vec<Lit>& ps, const Lit lit);
uint32_t numblockedClauseRemoved;
const bool tryOneSetting(const Lit lit, const Lit negLit);
priority_queue<VarOcc, vector<VarOcc>, MyComp> touchedBlockedVars;
vec<bool> touchedBlockedVarsBool;
void touchBlockedVar(const Var x);
double blockTime;
//validity checking
void verifyIntegrity();
uint32_t clauses_subsumed;
uint32_t literals_removed;
uint32_t origNClauses;
uint32_t numCalls;
bool fullSubsume;
uint32_t clauseID;
};
template <class T, class T2>
void maybeRemove(vec<T>& ws, const T2& elem)
{
if (ws.size() > 0)
removeW(ws, elem);
}
inline void Subsumer::touch(const Var x)
{
if (!touched[x]) {
touched[x] = 1;
touched_list.push(x);
}
}
inline void Subsumer::touchBlockedVar(const Var x)
{
if (!touchedBlockedVarsBool[x]) {
touchedBlockedVars.push(VarOcc(x, occur[Lit(x, false).toInt()].size()*occur[Lit(x, true).toInt()].size()));
touchedBlockedVarsBool[x] = 1;
}
}
inline void Subsumer::touch(const Lit p)
{
touch(p.var());
}
inline bool Subsumer::subsetAbst(uint32_t A, uint32_t B)
{
return !(A & ~B);
}
// Assumes 'seen' is cleared (will leave it cleared)
template<class T1, class T2>
bool Subsumer::subset(const T1& A, const T2& B)
{
for (uint32_t i = 0; i != B.size(); i++)
seen_tmp[B[i].toInt()] = 1;
for (uint32_t i = 0; i != A.size(); i++) {
if (!seen_tmp[A[i].toInt()]) {
for (uint32_t i = 0; i != B.size(); i++)
seen_tmp[B[i].toInt()] = 0;
return false;
}
}
for (uint32_t i = 0; i != B.size(); i++)
seen_tmp[B[i].toInt()] = 0;
return true;
}
inline void Subsumer::newVar()
{
occur .push();
occur .push();
seen_tmp .push(0); // (one for each polarity)
seen_tmp .push(0);
touched .push(1);
var_elimed .push(0);
touchedBlockedVarsBool.push(0);
cannot_eliminate.push(0);
}
inline const vec<char>& Subsumer::getVarElimed() const
{
return var_elimed;
}
inline const uint32_t Subsumer::getNumElimed() const
{
return numElimed;
}
inline const double Subsumer::getTotalTime() const
{
return totalTime;
}
#endif //SIMPLIFIER_H

View File

@ -0,0 +1,521 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "VarReplacer.h"
#include <iostream>
#include <iomanip>
#include "ClauseCleaner.h"
#include "PartHandler.h"
#include "time_mem.h"
//#define VERBOSE_DEBUG
//#define DEBUG_REPLACER
//#define REPLACE_STATISTICS
#ifdef VERBOSE_DEBUG
#include <iostream>
using std::cout;
using std::endl;
#endif
VarReplacer::VarReplacer(Solver& _solver) :
replacedLits(0)
, replacedVars(0)
, lastReplacedVars(0)
, solver(_solver)
{
}
VarReplacer::~VarReplacer()
{
for (uint i = 0; i != clauses.size(); i++)
clauseFree(clauses[i]);
}
const bool VarReplacer::performReplaceInternal()
{
#ifdef VERBOSE_DEBUG
cout << "Replacer started." << endl;
#endif
double time = cpuTime();
#ifdef REPLACE_STATISTICS
uint numRedir = 0;
for (uint i = 0; i < table.size(); i++) {
if (table[i].var() != i)
numRedir++;
}
std::cout << "Number of trees:" << reverseTable.size() << std::endl;
std::cout << "Number of redirected nodes:" << numRedir << std::endl;
/*map<Var, vector<Var> >::iterator it = reverseTable.begin();
map<Var, vector<Var> >::iterator end = reverseTable.end();
for (;it != end; it++) {
std::cout << "Tree size: " << it->second.size() << std::endl;
}*/
#endif //REPLACE_STATISTICS
solver.clauseCleaner->removeAndCleanAll(true);
if (!solver.ok) return false;
solver.testAllClauseAttach();
#ifdef VERBOSE_DEBUG
{
uint i = 0;
for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, i++) {
if (it->var() == i) continue;
cout << "Replacing var " << i+1 << " with Lit " << (it->sign() ? "-" : "") << it->var()+1 << endl;
}
}
#endif
Var var = 0;
const vec<char>& removedVars = solver.xorSubsumer->getVarElimed();
const vec<lbool>& removedVars2 = solver.partHandler->getSavedState();
const vec<char>& removedVars3 = solver.subsumer->getVarElimed();
for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, var++) {
if (it->var() == var || removedVars[it->var()] || removedVars2[it->var()] != l_Undef || removedVars3[it->var()]) continue;
#ifdef VERBOSE_DEBUG
cout << "Setting var " << var+1 << " to a non-decision var" << endl;
#endif
bool wasDecisionVar = solver.decision_var[var];
solver.setDecisionVar(var, false);
solver.setDecisionVar(it->var(), true);
uint32_t& activity1 = solver.activity[var];
uint32_t& activity2 = solver.activity[it->var()];
if (wasDecisionVar && activity1 > activity2) {
activity2 = activity1;
solver.order_heap.update(it->var());
solver.polarity[it->var()] = solver.polarity[var]^it->sign();
}
activity1 = 0;
solver.order_heap.update(var);
}
assert(solver.order_heap.heapProperty());
if (solver.verbosity >= 2)
std::cout << "c | Replacing " << std::setw(8) << replacedVars-lastReplacedVars << " vars" << std::flush;
lastReplacedVars = replacedVars;
solver.testAllClauseAttach();
if (!replace_set(solver.binaryClauses, true)) goto end;
if (!replace_set(solver.clauses, false)) goto end;
if (!replace_set(solver.learnts, false)) goto end;
if (!replace_set(solver.xorclauses)) goto end;
solver.testAllClauseAttach();
end:
for (uint i = 0; i != clauses.size(); i++)
solver.removeClause(*clauses[i]);
clauses.clear();
if (solver.verbosity >= 2) {
std::cout << " Replaced " << std::setw(8) << replacedLits<< " lits"
<< " Time: " << std::setw(8) << std::fixed << std::setprecision(2) << cpuTime()-time << " s "
<< std::setw(10) << " |" << std::endl;
}
replacedLits = 0;
solver.order_heap.filter(Solver::VarFilter(solver));
return solver.ok;
}
const bool VarReplacer::replace_set(vec<XorClause*>& cs)
{
XorClause **a = cs.getData();
XorClause **r = a;
for (XorClause **end = a + cs.size(); r != end; r++) {
XorClause& c = **r;
bool changed = false;
Var origVar1 = c[0].var();
Var origVar2 = c[1].var();
for (Lit *l = &c[0], *end2 = l + c.size(); l != end2; l++) {
Lit newlit = table[l->var()];
if (newlit.var() != l->var()) {
changed = true;
*l = Lit(newlit.var(), false);
c.invert(newlit.sign());
c.setVarChanged();
replacedLits++;
}
}
if (changed && handleUpdatedClause(c, origVar1, origVar2)) {
if (!solver.ok) {
for(;r != end; r++) clauseFree(*r);
cs.shrink(r-a);
return false;
}
c.setRemoved();
solver.freeLater.push(&c);
} else {
*a++ = *r;
}
}
cs.shrink(r-a);
return solver.ok;
}
const bool VarReplacer::handleUpdatedClause(XorClause& c, const Var origVar1, const Var origVar2)
{
uint origSize = c.size();
std::sort(c.getData(), c.getDataEnd());
Lit p;
uint32_t i, j;
for (i = j = 0, p = lit_Undef; i != c.size(); i++) {
if (c[i].var() == p.var()) {
//added, but easily removed
j--;
p = lit_Undef;
if (!solver.assigns[c[i].var()].isUndef())
c.invert(solver.assigns[c[i].var()].getBool());
} else if (solver.assigns[c[i].var()].isUndef()) //just add
c[j++] = p = c[i];
else c.invert(solver.assigns[c[i].var()].getBool()); //modify xor_clause_inverted instead of adding
}
c.shrink(i - j);
#ifdef VERBOSE_DEBUG
cout << "xor-clause after replacing: ";
c.plainPrint();
#endif
switch (c.size()) {
case 0:
solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
if (!c.xor_clause_inverted())
solver.ok = false;
return true;
case 1:
solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
solver.uncheckedEnqueue(Lit(c[0].var(), c.xor_clause_inverted()));
solver.ok = (solver.propagate() == NULL);
return true;
case 2: {
solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
c[0] = c[0].unsign();
c[1] = c[1].unsign();
addBinaryXorClause(c, c.xor_clause_inverted(), c.getGroup(), true);
return true;
}
default:
solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
solver.attachClause(c);
return false;
}
assert(false);
return false;
}
const bool VarReplacer::replace_set(vec<Clause*>& cs, const bool binClauses)
{
Clause **a = cs.getData();
Clause **r = a;
for (Clause **end = a + cs.size(); r != end; r++) {
Clause& c = **r;
bool changed = false;
Lit origLit1 = c[0];
Lit origLit2 = c[1];
for (Lit *l = c.getData(), *end2 = l + c.size(); l != end2; l++) {
if (table[l->var()].var() != l->var()) {
changed = true;
*l = table[l->var()] ^ l->sign();
c.setVarChanged();
replacedLits++;
}
}
if (changed && handleUpdatedClause(c, origLit1, origLit2)) {
if (!solver.ok) {
for(;r != end; r++) clauseFree(*r);
cs.shrink(r-a);
return false;
}
} else {
if (!binClauses && c.size() == 2) {
solver.becameBinary++;
solver.binaryClauses.push(&c);
} else
*a++ = *r;
}
}
cs.shrink(r-a);
return solver.ok;
}
const bool VarReplacer::handleUpdatedClause(Clause& c, const Lit origLit1, const Lit origLit2)
{
bool satisfied = false;
std::sort(c.getData(), c.getData() + c.size());
Lit p;
uint32_t i, j;
const uint origSize = c.size();
for (i = j = 0, p = lit_Undef; i != origSize; i++) {
if (solver.value(c[i]) == l_True || c[i] == ~p) {
satisfied = true;
break;
}
else if (solver.value(c[i]) != l_False && c[i] != p)
c[j++] = p = c[i];
}
c.shrink(i - j);
if (satisfied) {
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
return true;
}
switch(c.size()) {
case 0:
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
solver.ok = false;
return true;
case 1 :
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
solver.uncheckedEnqueue(c[0]);
solver.ok = (solver.propagate() == NULL);
return true;
default:
solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
solver.attachClause(c);
return false;
}
assert(false);
return false;
}
const vector<Var> VarReplacer::getReplacingVars() const
{
vector<Var> replacingVars;
for(map<Var, vector<Var> >::const_iterator it = reverseTable.begin(), end = reverseTable.end(); it != end; it++) {
replacingVars.push_back(it->first);
}
return replacingVars;
}
void VarReplacer::extendModelPossible() const
{
#ifdef VERBOSE_DEBUG
std::cout << "extendModelPossible() called" << std::endl;
#endif //VERBOSE_DEBUG
uint i = 0;
for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, i++) {
if (it->var() == i) continue;
#ifdef VERBOSE_DEBUG
cout << "Extending model: var "; solver.printLit(Lit(i, false));
cout << " to "; solver.printLit(*it);
cout << endl;
#endif
if (solver.assigns[it->var()] != l_Undef) {
if (solver.assigns[i] == l_Undef) {
bool val = (solver.assigns[it->var()] == l_False);
solver.uncheckedEnqueue(Lit(i, val ^ it->sign()));
} else {
assert(solver.assigns[i].getBool() == (solver.assigns[it->var()].getBool() ^ it->sign()));
}
}
solver.ok = (solver.propagate() == NULL);
assert(solver.ok);
}
}
void VarReplacer::extendModelImpossible(Solver& solver2) const
{
#ifdef VERBOSE_DEBUG
std::cout << "extendModelImpossible() called" << std::endl;
#endif //VERBOSE_DEBUG
vec<Lit> tmpClause;
uint i = 0;
for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, i++) {
if (it->var() == i) continue;
if (solver.assigns[it->var()] == l_Undef) {
assert(solver.assigns[it->var()] == l_Undef);
assert(solver.assigns[i] == l_Undef);
tmpClause.clear();
tmpClause.push(Lit(it->var(), true));
tmpClause.push(Lit(i, it->sign()));
solver2.addClause(tmpClause);
assert(solver2.ok);
tmpClause.clear();
tmpClause.push(Lit(it->var(), false));
tmpClause.push(Lit(i, it->sign()^true));
solver2.addClause(tmpClause);
assert(solver2.ok);
}
}
}
template<class T>
const bool VarReplacer::replace(T& ps, const bool xor_clause_inverted, const uint group)
{
// replace ps[0] with ps[1] (or -ps[1]) when xor_clause_inverted==true (or false)
#ifdef VERBOSE_DEBUG
std::cout << "replace() called with var " << ps[0].var()+1 << " and var " << ps[1].var()+1 << " with xor_clause_inverted " << xor_clause_inverted << std::endl;
#endif
assert(ps.size() == 2);
assert(!ps[0].sign());
assert(!ps[1].sign());
#ifdef DEBUG_REPLACER
assert(solver.assigns[ps[0].var()].isUndef());
assert(solver.assigns[ps[1].var()].isUndef());
#endif
Lit lit1 = table[ps[0].var()]; // lit1=ps[0] or to a' where already know that ps[0] == a'
Lit lit2 = table[ps[1].var()];
if(lit1.var() == lit2.var()) { // cycle
if(lit1.sign() ^ lit2.sign() == xor_clause_inverted) {
#ifdef VERBOSE_DEBUG
cout << "Inverted cycle in var-replacement -> UNSAT" << endl;
#endif
return (solver.ok = false);
}
return solver.ok;
}
if(lit1.sign() ^ !xor_clause_inverted) {
lit2 = ~lit2;
}
setAllThatPointsHereTo(lit1.var(), lit2);
replacedVars++;
addBinaryXorClause(ps, xor_clause_inverted, group);
return true;
}
template const bool VarReplacer::replace(vec<Lit>& ps, const bool xor_clause_inverted, const uint group);
template const bool VarReplacer::replace(XorClause& ps, const bool xor_clause_inverted, const uint group);
template<class T>
void VarReplacer::addBinaryXorClause(T& ps, const bool xor_clause_inverted, const uint group, const bool internal)
{
assert(internal || (replacedVars > lastReplacedVars));
#ifdef DEBUG_REPLACER
assert(!ps[0].sign());
assert(!ps[1].sign());
#endif
Clause* c;
ps[0] ^= xor_clause_inverted;
c = Clause_new(ps, group, false);
if (internal) {
solver.binaryClauses.push(c);
solver.becameBinary++;
} else
clauses.push(c);
solver.attachClause(*c);
ps[0] ^= true;
ps[1] ^= true;
c = Clause_new(ps, group, false);
if (internal) {
solver.binaryClauses.push(c);
solver.becameBinary++;
} else
clauses.push(c);
solver.attachClause(*c);
}
template void VarReplacer::addBinaryXorClause(vec<Lit>& ps, const bool xor_clause_inverted, const uint group, const bool internal);
template void VarReplacer::addBinaryXorClause(XorClause& ps, const bool xor_clause_inverted, const uint group, const bool internal);
/*
bool VarReplacer::alreadyIn(const Var var, const Lit lit)
{
Lit lit2 = table[var];
if (lit2.var() == lit.var()) {
if (lit2.sign() != lit.sign()) {
#ifdef VERBOSE_DEBUG
cout << "Inverted cycle in var-replacement -> UNSAT" << endl;
#endif
solver.ok = false;
}
return true;
}
lit2 = table[lit.var()];
if (lit2.var() == var) {
if (lit2.sign() != lit.sign()) {
#ifdef VERBOSE_DEBUG
cout << "Inverted cycle in var-replacement -> UNSAT" << endl;
#endif
solver.ok = false;
}
return true;
}
return false;
}
*/
void VarReplacer::setAllThatPointsHereTo(const Var var, const Lit lit)
{
map<Var, vector<Var> >::iterator it = reverseTable.find(var);
if (it != reverseTable.end()) {
for(vector<Var>::const_iterator it2 = it->second.begin(), end = it->second.end(); it2 != end; it2++) {
assert(table[*it2].var() == var);
if (lit.var() != *it2) {
table[*it2] = lit ^ table[*it2].sign();
reverseTable[lit.var()].push_back(*it2);
}
}
reverseTable.erase(it);
}
table[var] = lit;
reverseTable[lit.var()].push_back(var);
}
void VarReplacer::newVar()
{
table.push_back(Lit(table.size(), false));
}
void VarReplacer::reattachInternalClauses()
{
Clause **i = clauses.getData();
Clause **j = i;
for (Clause **end = clauses.getDataEnd(); i != end; i++) {
if (solver.value((**i)[0]) == l_Undef &&
solver.value((**i)[1]) == l_Undef) {
solver.attachClause(**i);
*j++ = *i;
}
}
clauses.shrink(i-j);
}

View File

@ -0,0 +1,147 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef VARREPLACER_H
#define VARREPLACER_H
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#include <map>
#include <vector>
using std::map;
using std::vector;
#include "Solver.h"
#include "SolverTypes.h"
#include "Clause.h"
#include "Vec.h"
class VarReplacer
{
public:
VarReplacer(Solver& solver);
~VarReplacer();
const bool performReplace(const bool always = false);
const bool needsReplace();
template<class T>
const bool replace(T& ps, const bool xor_clause_inverted, const uint group);
void extendModelPossible() const;
void extendModelImpossible(Solver& solver2) const;
void reattachInternalClauses();
const uint getNumReplacedLits() const;
const uint getNumReplacedVars() const;
const uint getNumLastReplacedVars() const;
const uint getNewToReplaceVars() const;
const uint32_t getNumTrees() const;
const vector<Var> getReplacingVars() const;
const vector<Lit>& getReplaceTable() const;
const vec<Clause*>& getClauses() const;
const bool varHasBeenReplaced(const Var var) const;
const bool replacingVar(const Var var) const;
void newVar();
private:
const bool performReplaceInternal();
const bool replace_set(vec<Clause*>& cs, const bool binClauses);
const bool replace_set(vec<XorClause*>& cs);
const bool handleUpdatedClause(Clause& c, const Lit origLit1, const Lit origLit2);
const bool handleUpdatedClause(XorClause& c, const Var origVar1, const Var origVar2);
template<class T>
void addBinaryXorClause(T& ps, const bool xor_clause_inverted, const uint group, const bool internal = false);
void setAllThatPointsHereTo(const Var var, const Lit lit);
// bool alreadyIn(const Var var, const Lit lit);
vector<Lit> table;
map<Var, vector<Var> > reverseTable;
vec<Clause*> clauses;
uint replacedLits;
uint replacedVars;
uint lastReplacedVars;
Solver& solver;
};
inline const bool VarReplacer::performReplace(const bool always)
{
//uint32_t limit = std::min((uint32_t)((double)solver.order_heap.size()*PERCENTAGEPERFORMREPLACE), FIXCLEANREPLACE);
uint32_t limit = (uint32_t)((double)solver.order_heap.size()*PERCENTAGEPERFORMREPLACE);
if ((always && getNewToReplaceVars() > 0) || getNewToReplaceVars() > limit)
return performReplaceInternal();
return true;
}
inline const bool VarReplacer::needsReplace()
{
uint32_t limit = (uint32_t)((double)solver.order_heap.size()*PERCENTAGEPERFORMREPLACE);
return (getNewToReplaceVars() > limit);
}
inline const uint VarReplacer::getNumReplacedLits() const
{
return replacedLits;
}
inline const uint VarReplacer::getNumReplacedVars() const
{
return replacedVars;
}
inline const uint VarReplacer::getNumLastReplacedVars() const
{
return lastReplacedVars;
}
inline const uint VarReplacer::getNewToReplaceVars() const
{
return replacedVars-lastReplacedVars;
}
inline const vector<Lit>& VarReplacer::getReplaceTable() const
{
return table;
}
inline const vec<Clause*>& VarReplacer::getClauses() const
{
return clauses;
}
inline const bool VarReplacer::varHasBeenReplaced(const Var var) const
{
return table[var].var() != var;
}
inline const bool VarReplacer::replacingVar(const Var var) const
{
return (reverseTable.find(var) != reverseTable.end());
}
inline const uint32_t VarReplacer::getNumTrees() const
{
return reverseTable.size();
}
#endif //VARREPLACER_H

131
packages/bee/cryptominisat-2.5.1/Solver/XSet.h vendored Executable file
View File

@ -0,0 +1,131 @@
/**************************************************************************************************
From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
**************************************************************************************************/
#ifndef XSET_H
#define XSET_H
#include "Vec.h"
#include <limits>
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
class XorClause;
template <class T>
uint32_t calcXorAbstraction(const T& ps) {
uint32_t abstraction = 0;
for (uint32_t i = 0; i != ps.size(); i++)
abstraction |= 1 << (ps[i].var() & 31);
return abstraction;
}
//#pragma pack(push)
//#pragma pack(1)
class XorClauseSimp
{
public:
XorClauseSimp(XorClause* c, const uint32_t _index) :
clause(c)
, index(_index)
{}
XorClause* clause;
uint32_t index;
};
//#pragma pack(pop)
class XSet {
vec<uint32_t> where; // Map clause ID to position in 'which'.
vec<XorClauseSimp> which; // List of clauses (for fast iteration). May contain 'Clause_NULL'.
vec<uint32_t> free; // List of positions holding 'Clause_NULL'.
public:
//XorClauseSimp& operator [] (uint32_t index) { return which[index]; }
void reserve(uint32_t size) { where.reserve(size);}
uint32_t size(void) const { return which.size(); }
uint32_t nElems(void) const { return which.size() - free.size(); }
bool add(const XorClauseSimp& c) {
assert(c.clause != NULL);
where.growTo(c.index+1, std::numeric_limits<uint32_t>::max());
if (where[c.index] != std::numeric_limits<uint32_t>::max()) {
return true;
}
if (free.size() > 0){
where[c.index] = free.last();
which[free.last()] = c;
free.pop();
}else{
where[c.index] = which.size();
which.push(c);
}
return false;
}
bool exclude(const XorClauseSimp& c) {
assert(c.clause != NULL);
if (c.index >= where.size() || where[c.index] == std::numeric_limits<uint32_t>::max()) {
//not inside
return false;
}
free.push(where[c.index]);
which[where[c.index]].clause = NULL;
where[c.index] = std::numeric_limits<uint32_t>::max();
return true;
}
void clear(void) {
for (uint32_t i = 0; i < which.size(); i++) {
if (which[i].clause != NULL) {
where[which[i].index] = std::numeric_limits<uint32_t>::max();
}
}
which.clear();
free.clear();
}
class iterator
{
public:
iterator(XorClauseSimp* _it) :
it(_it)
{}
void operator++()
{
it++;
}
const bool operator!=(const iterator& iter) const
{
return (it != iter.it);;
}
XorClauseSimp& operator*() {
return *it;
}
XorClauseSimp*& operator->() {
return it;
}
private:
XorClauseSimp* it;
};
iterator begin()
{
return iterator(which.getData());
}
iterator end()
{
return iterator(which.getData() + which.size());
}
};
#endif //XSET_H

View File

@ -0,0 +1,491 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#include "XorFinder.h"
#include <algorithm>
#include <utility>
#include <iostream>
#include "Solver.h"
#include "VarReplacer.h"
#include "ClauseCleaner.h"
#include "time_mem.h"
//#define VERBOSE_DEBUG
#ifdef _MSC_VER
#define __builtin_prefetch(a,b)
#endif //_MSC_VER
#ifdef VERBOSE_DEBUG
#include <iostream>
using std::cout;
using std::endl;
#endif
using std::make_pair;
XorFinder::XorFinder(Solver& _solver, vec<Clause*>& _cls, ClauseCleaner::ClauseSetType _type) :
cls(_cls)
, type(_type)
, solver(_solver)
{
}
const bool XorFinder::doNoPart(const uint minSize, const uint maxSize)
{
uint sumLengths = 0;
double time = cpuTime();
foundXors = 0;
solver.clauseCleaner->cleanClauses(solver.clauses, ClauseCleaner::clauses);
if (type == ClauseCleaner::binaryClauses) {
solver.clauseCleaner->cleanClauses(solver.binaryClauses, ClauseCleaner::binaryClauses);
}
if (!solver.ok) return false;
toRemove.clear();
toRemove.resize(cls.size(), false);
toLeaveInPlace.clear();
toLeaveInPlace.resize(cls.size(), false);
table.clear();
table.reserve(cls.size());
ClauseTable unsortedTable;
unsortedTable.reserve(cls.size());
ClauseTable sortedTable;
sortedTable.reserve(cls.size());
for (Clause **it = cls.getData(), **end = it + cls.size(); it != end; it ++) {
if (it+1 != end)
__builtin_prefetch(*(it+1), 0);
//if ((**it)[0].toInt() < (**it)[1].toInt())
// std::swap((**it)[0], (**it)[1]);
Clause& c = (**it);
if ((*it)->size() != 2) {
bool sorted = true;
for (uint i = 0, size = c.size(); i+1 < size ; i++) {
sorted = (c[i].var() <= c[i+1].var());
if (!sorted) break;
}
if (!sorted) {
solver.detachClause(c);
std::sort(c.getData(), c.getDataEnd());
solver.attachClause(c);
}
} else {
std::sort(c.getData(), c.getData()+c.size());
}
}
uint i = 0;
for (Clause **it = cls.getData(), **end = it + cls.size(); it != end; it++, i++) {
const uint size = (*it)->size();
if ( size > maxSize || size < minSize) {
toLeaveInPlace[i] = true;
continue;
}
if ((*it)->getSorted()) sortedTable.push_back(make_pair(*it, i));
else unsortedTable.push_back(make_pair(*it, i));
}
clause_sorter_primary sorter;
std::sort(unsortedTable.begin(), unsortedTable.end(), clause_sorter_primary());
//std::sort(sortedTable.begin(), sortedTable.end(), clause_sorter_primary());
#ifdef DEBUG_XORFIND
for (uint i = 0; i+1 < unsortedTable.size(); i++) {
assert(!sorter(unsortedTable[i+1], unsortedTable[i]));
}
for (uint i = 0; i+1 < sortedTable.size(); i++) {
assert(!sorter(sortedTable[i+1], sortedTable[i]));
}
#endif //DEBUG_XORFIND
for (uint i = 0, j = 0; i < unsortedTable.size() || j < sortedTable.size();) {
if (j == sortedTable.size()) {
table.push_back(unsortedTable[i++]);
continue;
}
if (i == unsortedTable.size()) {
table.push_back(sortedTable[j++]);
continue;
}
if (sorter(unsortedTable[i], sortedTable[j])) {
table.push_back(unsortedTable[i++]);
} else {
table.push_back(sortedTable[j++]);
}
}
#ifdef DEBUG_XORFIND
for (uint i = 0; i+1 < table.size(); i++) {
assert(!sorter(table[i+1], table[i]));
//table[i].first->plainPrint();
}
#endif //DEBUG_XORFIND
if (findXors(sumLengths) == false) goto end;
solver.ok = (solver.propagate() == NULL);
end:
if (minSize == maxSize && minSize == 2) {
if (solver.verbosity >= 2 || (solver.conflicts == 0 && solver.verbosity >= 1)) {
printf("c | Finding binary XORs: %5.2lf s (found: %7d, avg size: %3.1lf) |\n", cpuTime()-time, foundXors, (double)sumLengths/(double)foundXors);
}
} else {
if (solver.verbosity >= 2 || (solver.verbosity >= 1 && foundXors > 0)) {
printf("c | Finding non-binary XORs: %5.2lf s (found: %7d, avg size: %3.1lf) |\n", cpuTime()-time, foundXors, (double)sumLengths/(double)foundXors);
}
}
i = 0;
uint32_t j = 0;
uint32_t toSkip = 0;
for (uint end = cls.size(); i != end; i++) {
if (toLeaveInPlace[i]) {
cls[j] = cls[i];
j++;
toSkip++;
continue;
}
if (!toRemove[table[i-toSkip].second]) {
table[i-toSkip].first->setSorted();
cls[j] = table[i-toSkip].first;
j++;
}
}
cls.shrink(i-j);
return solver.ok;
}
const bool XorFinder::findXors(uint& sumLengths)
{
#ifdef VERBOSE_DEBUG
cout << "Finding Xors started" << endl;
#endif
sumLengths = 0;
ClauseTable::iterator begin = table.begin();
ClauseTable::iterator end = table.begin();
vec<Lit> lits;
bool impair;
while (getNextXor(begin, end, impair)) {
const Clause& c = *(begin->first);
lits.clear();
for (const Lit *it = &c[0], *cend = it+c.size() ; it != cend; it++) {
lits.push(Lit(it->var(), false));
}
uint old_group = c.getGroup();
#ifdef VERBOSE_DEBUG
cout << "- Found clauses:" << endl;
#endif
for (ClauseTable::iterator it = begin; it != end; it++)
if (impairSigns(*it->first) == impair){
#ifdef VERBOSE_DEBUG
it->first->plainPrint();
#endif
toRemove[it->second] = true;
solver.removeClause(*it->first);
}
switch(lits.size()) {
case 2: {
solver.varReplacer->replace(lits, impair, old_group);
#ifdef VERBOSE_DEBUG
XorClause* x = XorClause_new(lits, impair, old_group);
cout << "- Final 2-long xor-clause: ";
x->plainPrint();
clauseFree(x);
#endif
break;
}
default: {
XorClause* x = XorClause_new(lits, impair, old_group);
solver.xorclauses.push(x);
solver.attachClause(*x);
#ifdef VERBOSE_DEBUG
cout << "- Final xor-clause: ";
x->plainPrint();
#endif
}
}
foundXors++;
sumLengths += lits.size();
}
return solver.ok;
}
void XorFinder::clearToRemove()
{
assert(toRemove.size() == cls.size());
Clause **a = cls.getData();
Clause **r = cls.getData();
Clause **cend = cls.getData() + cls.size();
for (uint i = 0; r != cend; i++) {
if (!toRemove[i])
*a++ = *r++;
else
r++;
}
cls.shrink(r-a);
}
bool XorFinder::getNextXor(ClauseTable::iterator& begin, ClauseTable::iterator& end, bool& impair)
{
ClauseTable::iterator tableEnd = table.end();
while(begin != tableEnd && end != tableEnd) {
begin = end;
end++;
uint32_t size = (end == tableEnd ? 0:1);
while(end != tableEnd && clause_vareq(begin->first, end->first)) {
size++;
end++;
}
if (size > 0 && isXor(size, begin, end, impair))
return true;
}
return false;
}
bool XorFinder::clauseEqual(const Clause& c1, const Clause& c2) const
{
assert(c1.size() == c2.size());
for (uint i = 0, size = c1.size(); i < size; i++)
if (c1[i].sign() != c2[i].sign()) return false;
return true;
}
bool XorFinder::impairSigns(const Clause& c) const
{
uint num = 0;
for (const Lit *it = &c[0], *end = it + c.size(); it != end; it++)
num += it->sign();
return num % 2;
}
bool XorFinder::isXor(const uint32_t size, const ClauseTable::iterator& begin, const ClauseTable::iterator& end, bool& impair)
{
const uint requiredSize = 1 << (begin->first->size()-1);
if (size < requiredSize)
return false;
#ifdef DEBUG_XORFIND2
{
vec<Var> vars;
Clause& c = *begin->first;
for (uint i = 0; i < c.size(); i++)
vars.push(c[i].var());
for (ClauseTable::iterator it = begin; it != end; it++) {
Clause& c = *it->first;
for (uint i = 0; i < c.size(); i++)
assert(vars[i] == c[i].var());
}
clause_sorter_primary sorter;
for (ClauseTable::iterator it = begin; it != end; it++) {
ClauseTable::iterator it2 = it;
it2++;
if (it2 == end) break;
assert(!sorter(*it2, *it));
}
}
#endif //DEBUG_XORFIND
std::sort(begin, end, clause_sorter_secondary());
uint numPair = 0;
uint numImpair = 0;
countImpairs(begin, end, numImpair, numPair);
if (numImpair == requiredSize) {
impair = true;
return true;
}
if (numPair == requiredSize) {
impair = false;
return true;
}
return false;
}
void XorFinder::countImpairs(const ClauseTable::iterator& begin, const ClauseTable::iterator& end, uint& numImpair, uint& numPair) const
{
numImpair = 0;
numPair = 0;
ClauseTable::const_iterator it = begin;
ClauseTable::const_iterator it2 = begin;
it2++;
bool impair = impairSigns(*it->first);
numImpair += impair;
numPair += !impair;
for (; it2 != end;) {
if (!clauseEqual(*it->first, *it2->first)) {
bool impair = impairSigns(*it2->first);
numImpair += impair;
numPair += !impair;
}
it++;
it2++;
}
}
void XorFinder::addAllXorAsNorm()
{
uint32_t added = 0;
XorClause **i = solver.xorclauses.getData(), **j = i;
for (XorClause **end = solver.xorclauses.getDataEnd(); i != end; i++) {
if ((*i)->size() > 3) {
*j++ = *i;
continue;
}
added++;
if ((*i)->size() == 3) addXorAsNormal3(**i);
//if ((*i)->size() == 4) addXorAsNormal4(**i);
solver.removeClause(**i);
}
solver.xorclauses.shrink(i-j);
if (solver.verbosity >= 1) {
std::cout << "c | Added XOR as norm:" << added << std::endl;
}
}
void XorFinder::addXorAsNormal3(XorClause& c)
{
assert(c.size() == 3);
Clause *tmp;
vec<Var> vars;
vec<Lit> vars2(c.size());
const bool inverted = c.xor_clause_inverted();
for (uint32_t i = 0; i < c.size(); i++) {
vars.push(c[i].var());
}
vars2[0] = Lit(vars[0], false ^ inverted);
vars2[1] = Lit(vars[1], false ^ inverted);
vars2[2] = Lit(vars[2], false ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], true ^ inverted);
vars2[1] = Lit(vars[1], true ^ inverted);
vars2[2] = Lit(vars[2], false ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], true ^ inverted);
vars2[1] = Lit(vars[1], false ^ inverted);
vars2[2] = Lit(vars[2], true ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], false ^ inverted);
vars2[1] = Lit(vars[1], true ^ inverted);
vars2[2] = Lit(vars[2], true ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
}
void XorFinder::addXorAsNormal4(XorClause& c)
{
assert(c.size() == 4);
Clause *tmp;
vec<Var> vars;
vec<Lit> vars2(c.size());
const bool inverted = !c.xor_clause_inverted();
for (uint32_t i = 0; i < c.size(); i++) {
vars.push(c[i].var());
}
vars2[0] = Lit(vars[0], false ^ inverted);
vars2[1] = Lit(vars[1], false ^ inverted);
vars2[2] = Lit(vars[2], false ^ inverted);
vars2[3] = Lit(vars[3], true ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], false ^ inverted);
vars2[1] = Lit(vars[1], true ^ inverted);
vars2[2] = Lit(vars[2], false ^ inverted);
vars2[3] = Lit(vars[3], false ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], false ^ inverted);
vars2[1] = Lit(vars[1], false ^ inverted);
vars2[2] = Lit(vars[2], true ^ inverted);
vars2[3] = Lit(vars[3], false ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], false ^ inverted);
vars2[1] = Lit(vars[1], false ^ inverted);
vars2[2] = Lit(vars[2], false ^ inverted);
vars2[3] = Lit(vars[3], true ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], false ^ inverted);
vars2[1] = Lit(vars[1], true ^ inverted);
vars2[2] = Lit(vars[2], true ^ inverted);
vars2[3] = Lit(vars[3], true ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], true ^ inverted);
vars2[1] = Lit(vars[1], false ^ inverted);
vars2[2] = Lit(vars[2], true ^ inverted);
vars2[3] = Lit(vars[3], true ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], true ^ inverted);
vars2[1] = Lit(vars[1], true ^ inverted);
vars2[2] = Lit(vars[2], false ^ inverted);
vars2[3] = Lit(vars[3], true ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
vars2[0] = Lit(vars[0], true ^ inverted);
vars2[1] = Lit(vars[1], true ^ inverted);
vars2[2] = Lit(vars[2], true ^ inverted);
vars2[3] = Lit(vars[3], false ^ inverted);
tmp = solver.addClauseInt(vars2, c.getGroup());
if (tmp) solver.clauses.push(tmp);
}

View File

@ -0,0 +1,141 @@
/***********************************************************************************
CryptoMiniSat -- Copyright (c) 2009 Mate Soos
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
**************************************************************************************************/
#ifndef XORFINDER_H
#define XORFINDER_H
#ifdef _MSC_VER
#include <msvc/stdint.h>
#else
#include <stdint.h>
#endif //_MSC_VER
#define DEBUG_XORFIND
//#define DEBUG_XORFIND2
#include "Clause.h"
#include "VarReplacer.h"
#include "ClauseCleaner.h"
class Solver;
using std::pair;
class XorFinder
{
public:
XorFinder(Solver& _solver, vec<Clause*>& cls, ClauseCleaner::ClauseSetType _type);
const bool doNoPart(const uint minSize, const uint maxSize);
void addAllXorAsNorm();
private:
typedef vector<pair<Clause*, uint> > ClauseTable;
const bool findXors(uint& sumLengths);
bool getNextXor(ClauseTable::iterator& begin, ClauseTable::iterator& end, bool& impair);
struct clause_hasher {
size_t operator()(const Clause* c) const
{
size_t hash = 5381;
hash = ((hash << 5) + hash) ^ c->size();
for (uint i = 0, size = c->size(); i < size; i++)
hash = ((hash << 5) + hash) ^ (*c)[i].var();
return hash;
}
};
struct clause_sorter_primary {
bool operator()(const pair<Clause*, uint>& c11, const pair<Clause*, uint>& c22)
{
if (c11.first->size() != c22.first->size())
return (c11.first->size() < c22.first->size());
#ifdef DEBUG_XORFIND2
Clause& c1 = *c11.first;
for (uint i = 0; i+1 < c1.size(); i++)
assert(c1[i].var() <= c1[i+1].var());
Clause& c2 = *c22.first;
for (uint i = 0; i+1 < c2.size(); i++)
assert(c2[i].var() <= c2[i+1].var());
#endif //DEBUG_XORFIND2
for (a = c11.first->getData(), b = c22.first->getData(), end = a + c11.first->size(); a != end; a++, b++) {
if (a->var() != b->var())
return (a->var() > b->var());
}
return false;
}
Lit const *a;
Lit const *b;
Lit const *end;
};
struct clause_sorter_secondary {
bool operator()(const pair<Clause*, uint>& c11, const pair<Clause*, uint>& c22) const
{
const Clause& c1 = *(c11.first);
const Clause& c2 = *(c22.first);
for (uint i = 0, size = c1.size(); i < size; i++) {
if (c1[i].sign() != c2[i].sign())
return c1[i].sign();
}
return false;
}
};
bool clause_vareq(const Clause* c1, const Clause* c2) const
{
if (c1->size() != c2->size())
return false;
for (uint i = 0, size = c1->size(); i < size; i++)
if ((*c1)[i].var() != (*c2)[i].var())
return false;
return true;
}
ClauseTable table;
vector<bool> toRemove;
vector<bool> toLeaveInPlace;
void clearToRemove();
uint32_t foundXors;
//For adding xor as norm
void addXorAsNormal3(XorClause& c);
void addXorAsNormal4(XorClause& c);
vec<Clause*>& cls;
ClauseCleaner::ClauseSetType type;
bool clauseEqual(const Clause& c1, const Clause& c2) const;
bool impairSigns(const Clause& c) const;
void countImpairs(const ClauseTable::iterator& begin, const ClauseTable::iterator& end, uint& numImpair, uint& numPair) const;
bool isXor(const uint32_t size, const ClauseTable::iterator& begin, const ClauseTable::iterator& end, bool& impair);
Solver& solver;
};
#endif //XORFINDER_H

View File

@ -0,0 +1,600 @@
/**************************************************************************************************
Originally From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
Substantially modified by: Mate Soos (2010)
**************************************************************************************************/
#include "Solver.h"
#include "XorSubsumer.h"
#include "ClauseCleaner.h"
#include "time_mem.h"
#include "assert.h"
#include <iomanip>
#include "VarReplacer.h"
#ifdef _MSC_VER
#define __builtin_prefetch(a,b,c)
#endif //_MSC_VER
//#define VERBOSE_DEBUG
#ifdef VERBOSE_DEBUG
#define VERBOSE_DEBUGSUBSUME0
#define BIT_MORE_VERBOSITY
#endif
#ifdef VERBOSE_DEBUG
using std::cout;
using std::endl;
#endif //VERBOSE_DEBUG
XorSubsumer::XorSubsumer(Solver& s):
solver(s)
, totalTime(0.0)
, numElimed(0)
, localSubstituteUseful(0)
{
};
// Will put NULL in 'cs' if clause removed.
void XorSubsumer::subsume0(XorClauseSimp& ps)
{
#ifdef VERBOSE_DEBUGSUBSUME0
cout << "subsume0 orig clause:";
ps.clause->plainPrint();
#endif
vec<Lit> origClause(ps.clause->size());
std::copy(ps.clause->getData(), ps.clause->getDataEnd(), origClause.getData());
const bool origClauseInverted = ps.clause->xor_clause_inverted();
vec<Lit> unmatchedPart;
bool needUnlinkPS = false;
vec<XorClauseSimp> subs;
findSubsumed(*ps.clause, subs);
for (uint32_t i = 0; i < subs.size(); i++){
XorClause* tmp = subs[i].clause;
findUnMatched(origClause, *tmp, unmatchedPart);
if (unmatchedPart.size() == 0) {
#ifdef VERBOSE_DEBUGSUBSUME0
cout << "subsume0 removing:";
subs[i].clause->plainPrint();
#endif
clauses_subsumed++;
assert(tmp->size() == origClause.size());
if (origClauseInverted == tmp->xor_clause_inverted()) {
unlinkClause(subs[i]);
clauseFree(tmp);
} else {
solver.ok = false;
return;
}
} else {
assert(unmatchedPart.size() > 0);
clauses_cut++;
#ifdef VERBOSE_DEBUG
std::cout << "Cutting xor-clause:";
subs[i].clause->plainPrint();
#endif //VERBOSE_DEBUG
XorClause *c = solver.addXorClauseInt(unmatchedPart, tmp->xor_clause_inverted() ^ !origClauseInverted, tmp->getGroup());
if (c != NULL) {
linkInClause(*c);
needUnlinkPS = true;
}
if (!solver.ok) return;
}
unmatchedPart.clear();
}
if (needUnlinkPS) {
XorClause* tmp = ps.clause;
unlinkClause(ps);
clauseFree(tmp);
}
}
void XorSubsumer::findUnMatched(vec<Lit>& A, XorClause& B, vec<Lit>& unmatchedPart)
{
for (uint32_t i = 0; i != B.size(); i++)
seen_tmp[B[i].var()] = 1;
for (uint32_t i = 0; i != A.size(); i++)
seen_tmp[A[i].var()] = 0;
for (uint32_t i = 0; i != B.size(); i++) {
if (seen_tmp[B[i].var()] == 1) {
unmatchedPart.push(Lit(B[i].var(), false));
seen_tmp[B[i].var()] = 0;
}
}
}
void XorSubsumer::unlinkClause(XorClauseSimp c, const Var elim)
{
XorClause& cl = *c.clause;
for (uint32_t i = 0; i < cl.size(); i++) {
maybeRemove(occur[cl[i].var()], &cl);
}
if (elim != var_Undef)
elimedOutVar[elim].push_back(c.clause);
solver.detachClause(cl);
clauses[c.index].clause = NULL;
}
void XorSubsumer::unlinkModifiedClause(vec<Lit>& origClause, XorClauseSimp c)
{
for (uint32_t i = 0; i < origClause.size(); i++) {
maybeRemove(occur[origClause[i].var()], c.clause);
}
solver.detachModifiedClause(origClause[0].var(), origClause[1].var(), origClause.size(), c.clause);
clauses[c.index].clause = NULL;
}
void XorSubsumer::unlinkModifiedClauseNoDetachNoNULL(vec<Lit>& origClause, XorClauseSimp c)
{
for (uint32_t i = 0; i < origClause.size(); i++) {
maybeRemove(occur[origClause[i].var()], c.clause);
}
}
XorClauseSimp XorSubsumer::linkInClause(XorClause& cl)
{
XorClauseSimp c(&cl, clauseID++);
clauses.push(c);
for (uint32_t i = 0; i < cl.size(); i++) {
occur[cl[i].var()].push(c);
}
return c;
}
void XorSubsumer::linkInAlreadyClause(XorClauseSimp& c)
{
XorClause& cl = *c.clause;
for (uint32_t i = 0; i < c.clause->size(); i++) {
occur[cl[i].var()].push(c);
}
}
void XorSubsumer::addFromSolver(vec<XorClause*>& cs)
{
clauseID = 0;
clauses.clear();
XorClause **i = cs.getData();
for (XorClause **end = i + cs.size(); i != end; i++) {
if (i+1 != end)
__builtin_prefetch(*(i+1), 1, 1);
linkInClause(**i);
if ((*i)->getVarChanged() || (*i)->getStrenghtened())
(*i)->calcXorAbstraction();
}
cs.clear();
cs.push(NULL); //HACK --to force xor-propagation
}
void XorSubsumer::addBackToSolver()
{
solver.xorclauses.pop(); //HACK --to force xor-propagation
for (uint32_t i = 0; i < clauses.size(); i++) {
if (clauses[i].clause != NULL) {
solver.xorclauses.push(clauses[i].clause);
clauses[i].clause->unsetStrenghtened();
clauses[i].clause->unsetVarChanged();
}
}
for (Var var = 0; var < solver.nVars(); var++) {
occur[var].clear();
}
clauses.clear();
clauseID = 0;
}
void XorSubsumer::fillCannotEliminate()
{
std::fill(cannot_eliminate.getData(), cannot_eliminate.getDataEnd(), false);
for (uint32_t i = 0; i < solver.clauses.size(); i++)
addToCannotEliminate(solver.clauses[i]);
for (uint32_t i = 0; i < solver.binaryClauses.size(); i++)
if (!(*solver.binaryClauses[i]).learnt()) addToCannotEliminate(solver.binaryClauses[i]);
const vec<Clause*>& tmp = solver.varReplacer->getClauses();
for (uint32_t i = 0; i < tmp.size(); i++)
addToCannotEliminate(tmp[i]);
for (uint32_t i = 0; i < solver.assumptions.size(); i++)
cannot_eliminate[solver.assumptions[i].var()] = true;
#ifdef VERBOSE_DEBUG
uint32_t tmpNum = 0;
for (uint32_t i = 0; i < cannot_eliminate.size(); i++)
if (cannot_eliminate[i])
tmpNum++;
std::cout << "Cannot eliminate num:" << tmpNum << std::endl;
#endif
}
void XorSubsumer::extendModel(Solver& solver2)
{
assert(checkElimedUnassigned());
vec<Lit> tmp;
typedef map<Var, vector<XorClause*> > elimType;
for (elimType::iterator it = elimedOutVar.begin(), end = elimedOutVar.end(); it != end; it++) {
#ifdef VERBOSE_DEBUG
Var var = it->first;
std::cout << "Reinserting elimed var: " << var+1 << std::endl;
#endif
for (vector<XorClause*>::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) {
XorClause& c = **it2;
#ifdef VERBOSE_DEBUG
std::cout << "Reinserting Clause: ";
c.plainPrint();
#endif
tmp.clear();
tmp.growTo(c.size());
std::copy(c.getData(), c.getDataEnd(), tmp.getData());
bool inverted = c.xor_clause_inverted();
solver2.addXorClause(tmp, inverted);
assert(solver2.ok);
}
}
}
const bool XorSubsumer::localSubstitute()
{
vec<Lit> tmp;
for (Var var = 0; var < occur.size(); var++) {
vec<XorClauseSimp>& occ = occur[var];
if (occ.size() <= 1) continue;
for (uint32_t i = 0; i < occ.size(); i++) {
XorClause& c1 = *occ[i].clause;
for (uint32_t i2 = i+1; i2 < occ.size(); i2++) {
XorClause& c2 = *occ[i2].clause;
tmp.clear();
tmp.growTo(c1.size() + c2.size());
std::copy(c1.getData(), c1.getDataEnd(), tmp.getData());
std::copy(c2.getData(), c2.getDataEnd(), tmp.getData() + c1.size());
clearDouble(tmp);
if (tmp.size() <= 2) {
#ifdef VERBOSE_DEBUG
std::cout << "Local substiuting. Clause1:"; c1.plainPrint();
std::cout << "Clause 2:"; c2.plainPrint();
#endif //VERBOSE_DEBUG
localSubstituteUseful++;
uint32_t lastSize = solver.varReplacer->getClauses().size();
solver.addXorClauseInt(tmp, c1.xor_clause_inverted() ^ !c2.xor_clause_inverted(), c1.getGroup());
for (uint32_t i = lastSize; i < solver.varReplacer->getClauses().size(); i++)
addToCannotEliminate(solver.varReplacer->getClauses()[i]);
if (!solver.ok) {
#ifdef VERBOSE_DEBUG
std::cout << "solver.ok is false after local substitution" << std::endl;
#endif //VERBOSE_DEBUG
return false;
}
}
}
}
}
return true;
}
void XorSubsumer::clearDouble(vec<Lit>& ps) const
{
std::sort(ps.getData(), ps.getDataEnd());
Lit p;
uint32_t i, j;
for (i = j = 0, p = lit_Undef; i != ps.size(); i++) {
if (ps[i].var() == p.var()) {
//added, but easily removed
j--;
p = lit_Undef;
} else
ps[j++] = p = ps[i];
}
ps.shrink(i - j);
}
void XorSubsumer::removeWrong(vec<Clause*>& cs)
{
Clause **i = cs.getData();
Clause **j = i;
for (Clause **end = i + cs.size(); i != end; i++) {
Clause& c = **i;
if (!c.learnt()) {
*j++ = *i;
continue;
}
bool remove = false;
for (Lit *l = c.getData(), *end2 = l+c.size(); l != end2; l++) {
if (var_elimed[l->var()]) {
remove = true;
solver.detachClause(c);
clauseFree(&c);
break;
}
}
if (!remove)
*j++ = *i;
}
cs.shrink(i-j);
}
const bool XorSubsumer::removeDependent()
{
for (Var var = 0; var < occur.size(); var++) {
if (cannot_eliminate[var] || !solver.decision_var[var] || solver.assigns[var] != l_Undef) continue;
vec<XorClauseSimp>& occ = occur[var];
if (occ.size() == 1) {
#ifdef VERBOSE_DEBUG
std::cout << "Eliminating dependent var " << var + 1 << std::endl;
std::cout << "-> Removing dependent clause "; occ[0].clause->plainPrint();
#endif //VERBOSE_DEBUG
unlinkClause(occ[0], var);
solver.setDecisionVar(var, false);
var_elimed[var] = true;
numElimed++;
} else if (occ.size() == 2) {
vec<Lit> lits;
XorClause& c1 = *(occ[0].clause);
lits.growTo(c1.size());
std::copy(c1.getData(), c1.getDataEnd(), lits.getData());
bool inverted = c1.xor_clause_inverted();
XorClause& c2 = *(occ[1].clause);
lits.growTo(lits.size() + c2.size());
std::copy(c2.getData(), c2.getDataEnd(), lits.getData() + c1.size());
inverted ^= !c2.xor_clause_inverted();
uint32_t group = c2.getGroup();
#ifdef VERBOSE_DEBUG
std::cout << "Eliminating var " << var + 1 << " present in 2 xor-clauses" << std::endl;
std::cout << "-> Removing xor clause "; occ[0].clause->plainPrint();
std::cout << "-> Removing xor clause "; occ[1].clause->plainPrint();
#endif //VERBOSE_DEBUG
XorClauseSimp toUnlink0 = occ[0];
XorClauseSimp toUnlink1 = occ[1];
unlinkClause(toUnlink0);
clauseFree(toUnlink0.clause);
unlinkClause(toUnlink1, var);
solver.setDecisionVar(var, false);
var_elimed[var] = true;
numElimed++;
uint32_t lastSize = solver.varReplacer->getClauses().size();
XorClause* c = solver.addXorClauseInt(lits, inverted, group);
#ifdef VERBOSE_DEBUG
if (c != NULL) {
std::cout << "-> Added combined xor clause:"; c->plainPrint();
} else
std::cout << "-> Combined xor clause is NULL" << std::endl;
#endif
if (c != NULL) linkInClause(*c);
for (uint32_t i = lastSize; i < solver.varReplacer->getClauses().size(); i++)
addToCannotEliminate(solver.varReplacer->getClauses()[i]);
if (!solver.ok) {
#ifdef VERBOSE_DEBUG
std::cout << "solver.ok is false after var-elim through xor" << std::endl;
#endif //VERBOSE_DEBUG
return false;
}
}
}
return true;
}
inline void XorSubsumer::addToCannotEliminate(Clause* it)
{
const Clause& c = *it;
for (uint32_t i2 = 0; i2 < c.size(); i2++)
cannot_eliminate[c[i2].var()] = true;
}
const bool XorSubsumer::unEliminate(const Var var)
{
assert(var_elimed[var]);
typedef map<Var, vector<XorClause*> > elimType;
elimType::iterator it = elimedOutVar.find(var);
//MUST set to decision, since it would never have been eliminated
//had it not been decision var
solver.setDecisionVar(var, true);
var_elimed[var] = false;
numElimed--;
assert(it != elimedOutVar.end());
FILE* backup_libraryCNFfile = solver.libraryCNFFile;
solver.libraryCNFFile = NULL;
for (vector<XorClause*>::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) {
XorClause& c = **it2;
solver.addXorClause(c, c.xor_clause_inverted());
clauseFree(&c);
}
solver.libraryCNFFile = backup_libraryCNFfile;
elimedOutVar.erase(it);
return solver.ok;
}
const bool XorSubsumer::simplifyBySubsumption(const bool doFullSubsume)
{
double myTime = cpuTime();
uint32_t origTrailSize = solver.trail.size();
clauses_subsumed = 0;
clauses_cut = 0;
clauseID = 0;
uint32_t lastNumElimed = numElimed;
localSubstituteUseful = 0;
while (solver.performReplace && solver.varReplacer->needsReplace()) {
if (!solver.varReplacer->performReplace())
return false;
}
for (Var var = 0; var < solver.nVars(); var++) {
occur[var].clear();
}
solver.findAllAttach();
solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses);
if (!solver.ok) return false;
solver.testAllClauseAttach();
clauses.clear();
clauses.reserve(solver.xorclauses.size());
addFromSolver(solver.xorclauses);
#ifdef BIT_MORE_VERBOSITY
std::cout << "c time to link in:" << cpuTime()-myTime << std::endl;
#endif
origNClauses = clauses.size();
if (!solver.ok) return false;
#ifdef VERBOSE_DEBUG
std::cout << "c clauses:" << clauses.size() << std::endl;
#endif
bool replaced = true;
bool propagated = false;
while (replaced || propagated) {
replaced = propagated = false;
for (uint32_t i = 0; i < clauses.size(); i++) {
if (clauses[i].clause != NULL) {
subsume0(clauses[i]);
if (!solver.ok) {
addBackToSolver();
return false;
}
}
}
propagated = (solver.qhead != solver.trail.size());
solver.ok = (solver.propagate() == NULL);
if (!solver.ok) {
std::cout << "c (contradiction during subsumption)" << std::endl;
return false;
}
solver.clauseCleaner->cleanXorClausesBewareNULL(clauses, ClauseCleaner::xorSimpClauses, *this);
if (!solver.ok) return false;
testAllClauseAttach();
fillCannotEliminate();
if (solver.conglomerateXors && !removeDependent()) {
addBackToSolver();
return false;
}
testAllClauseAttach();
if (solver.heuleProcess && !localSubstitute()) {
addBackToSolver();
return false;
}
testAllClauseAttach();
/*if (solver.performReplace && solver.varReplacer->needsReplace()) {
addBackToSolver();
while (solver.performReplace && solver.varReplacer->needsReplace()) {
replaced = true;
if (!solver.varReplacer->performReplace())
return false;
}
addFromSolver(solver.xorclauses);
}*/
}
solver.order_heap.filter(Solver::VarFilter(solver));
removeWrong(solver.learnts);
removeWrong(solver.binaryClauses);
addBackToSolver();
if (solver.verbosity >= 1) {
std::cout << "c | x-sub: " << std::setw(5) << clauses_subsumed
<< " x-cut: " << std::setw(6) << clauses_cut
<< " vfix: " << std::setw(6) <<solver.trail.size() - origTrailSize
<< " v-elim: " <<std::setw(6) << numElimed - lastNumElimed
<< " locsubst:" << std::setw(6) << localSubstituteUseful
<< " time: " << std::setw(6) << std::setprecision(2) << (cpuTime() - myTime)
<< std::setw(3) << " |" << std::endl;
}
totalTime += cpuTime() - myTime;
solver.testAllClauseAttach();
return true;
}
#ifdef DEBUG_ATTACH
void XorSubsumer::testAllClauseAttach() const
{
for (const XorClauseSimp *it = clauses.getData(), *end = clauses.getDataEnd(); it != end; it++) {
if (it->clause == NULL) continue;
const XorClause& c = *it->clause;
assert(find(solver.xorwatches[c[0].var()], &c));
assert(find(solver.xorwatches[c[1].var()], &c));
if (solver.assigns[c[0].var()]!=l_Undef || solver.assigns[c[1].var()]!=l_Undef) {
for (uint i = 0; i < c.size();i++) {
assert(solver.assigns[c[i].var()] != l_Undef);
}
}
}
}
#else
inline void XorSubsumer::testAllClauseAttach() const
{
return;
}
#endif //DEBUG_ATTACH
void XorSubsumer::findSubsumed(XorClause& ps, vec<XorClauseSimp>& out_subsumed)
{
#ifdef VERBOSE_DEBUGSUBSUME0
cout << "findSubsumed: ";
for (uint32_t i = 0; i < ps.size(); i++) {
if (ps[i].sign()) printf("-");
printf("%d ", ps[i].var() + 1);
}
printf("0\n");
#endif
uint32_t min_i = 0;
for (uint32_t i = 1; i < ps.size(); i++){
if (occur[ps[i].var()].size() < occur[ps[min_i].var()].size())
min_i = i;
}
vec<XorClauseSimp>& cs = occur[ps[min_i].var()];
for (XorClauseSimp *it = cs.getData(), *end = it + cs.size(); it != end; it++){
if (it+1 != end)
__builtin_prefetch((it+1)->clause, 1, 1);
if (it->clause != &ps && subsetAbst(ps.getAbst(), it->clause->getAbst()) && ps.size() <= it->clause->size() && subset(ps, *it->clause)) {
out_subsumed.push(*it);
#ifdef VERBOSE_DEBUGSUBSUME0
cout << "subsumed: ";
it->clause->plainPrint();
#endif
}
}
}
const bool XorSubsumer::checkElimedUnassigned() const
{
for (uint32_t i = 0; i < var_elimed.size(); i++) {
if (var_elimed[i]) {
assert(solver.assigns[i] == l_Undef);
if (solver.assigns[i] != l_Undef) return false;
}
}
return true;
}

Some files were not shown because too many files have changed in this diff Show More