Commit 9e46ebe3 by Alan Mishchenko

Adding Glucose 3.0 as a separate package.

parent 7857b7fd
......@@ -2174,6 +2174,114 @@ SOURCE=.\src\sat\xsat\xsatUtils.h
SOURCE=.\src\sat\xsat\xsatWatchList.h
# End Source File
# End Group
# Begin Group "glucose"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\src\sat\glucose\AbcGlucose.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\AbcGlucose.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\AbcGlucoseCmd.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Alg.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Alloc.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\BoundedQueue.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Constants.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Dimacs.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Glucose.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Heap.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\IntTypes.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Map.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Options.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Options.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\ParseUtils.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\pstdint.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Queue.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\SimpSolver.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\SimpSolver.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Solver.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\SolverTypes.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Sort.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\System.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\System.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\Vec.h
# End Source File
# Begin Source File
SOURCE=.\src\sat\glucose\XAlloc.h
# End Source File
# End Group
# End Group
# Begin Group "opt"
......
......@@ -61,6 +61,8 @@ extern void Abc2_Init( Abc_Frame_t * pAbc );
extern void Abc2_End ( Abc_Frame_t * pAbc );
extern void Abc85_Init( Abc_Frame_t * pAbc );
extern void Abc85_End( Abc_Frame_t * pAbc );
extern void Glucose_Init( Abc_Frame_t * pAbc );
extern void Glucose_End( Abc_Frame_t * pAbc );
static Abc_FrameInitializer_t* s_InitializerStart = NULL;
static Abc_FrameInitializer_t* s_InitializerEnd = NULL;
......@@ -114,6 +116,7 @@ void Abc_FrameInit( Abc_Frame_t * pAbc )
Cba_Init( pAbc );
Pla_Init( pAbc );
Test_Init( pAbc );
Glucose_Init( pAbc );
for( p = s_InitializerStart ; p ; p = p->next )
if(p->init)
p->init(pAbc);
......@@ -152,6 +155,7 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc )
Cba_End( pAbc );
Pla_End( pAbc );
Test_End( pAbc );
Glucose_End( pAbc );
}
......
/**CFile****************************************************************
FileName [AbcGlucose.cpp]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT solver Glucose 3.0.]
Synopsis [Interface to Glucose.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 6, 2017.]
Revision [$Id: AbcGlucose.cpp,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sat/glucose/System.h"
#include "sat/glucose/ParseUtils.h"
#include "sat/glucose/Options.h"
#include "sat/glucose/Dimacs.h"
#include "sat/glucose/SimpSolver.h"
#include "sat/glucose/AbcGlucose.h"
#include "aig/gia/gia.h"
#include "sat/cnf/cnf.h"
using namespace Glucose;
ABC_NAMESPACE_IMPL_START
extern "C" {
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Glucose::Solver * glucose_solver_start()
{
Solver * S = new Solver;
S->setIncrementalMode();
return S;
}
void glucose_solver_stop(Glucose::Solver* S)
{
delete S;
}
int glucose_solver_addclause(Glucose::Solver* S, int * plits, int nlits)
{
vec<Lit> lits;
for ( int i = 0; i < nlits; i++,plits++)
{
// note: Glucose uses the same var->lit conventiaon as ABC
while ((*plits)/2 >= S->nVars()) S->newVar();
assert((*plits)/2 < S->nVars()); // NOTE: since we explicitely use new function bmc_add_var
Lit p;
p.x = *plits;
lits.push(p);
}
return S->addClause(lits); // returns 0 if the problem is UNSAT
}
int glucose_solver_setcallback(Glucose::Solver* S, void * pman, int(*pfunc)(void*, int, int*))
{
S->pCnfMan = pman;
S->pCnfFunc = pfunc;
S->nCallConfl = 1000;
return 0;
}
int glucose_solver_solve(Glucose::Solver* S, int * plits, int nlits)
{
vec<Lit> lits;
for (int i=0;i<nlits;i++,plits++)
{
Lit p;
p.x = *plits;
lits.push(p);
}
Glucose::lbool res = S->solveLimited(lits);
return (res == l_True ? 1 : res == l_False ? -1 : 0);
}
int glucose_solver_addvar(Glucose::Solver* S)
{
S->newVar();
return S->nVars() - 1;
}
int glucose_solver_read_cex_varvalue(Glucose::Solver* S, int ivar)
{
return S->model[ivar] == l_True;
}
void glucose_solver_setstop(Glucose::Solver* S, int * pstop)
{
S->pstop = pstop;
}
void glucose_print_stats(Solver& s, abctime clk)
{
double cpu_time = (double)(unsigned)clk / CLOCKS_PER_SEC;
double mem_used = memUsed();
printf("c restarts : %d (%d conflicts on average)\n", (int)s.starts, s.starts > 0 ? s.conflicts/s.starts : 0);
printf("c blocked restarts : %d (multiple: %d) \n", (int)s.nbstopsrestarts,s.nbstopsrestartssame);
printf("c last block at restart : %d\n", (int)s.lastblockatrestart);
printf("c nb ReduceDB : %-12d\n", (int)s.nbReduceDB);
printf("c nb removed Clauses : %-12d\n", (int)s.nbRemovedClauses);
printf("c nb learnts DL2 : %-12d\n", (int)s.nbDL2);
printf("c nb learnts size 2 : %-12d\n", (int)s.nbBin);
printf("c nb learnts size 1 : %-12d\n", (int)s.nbUn);
printf("c conflicts : %-12d (%.0f /sec)\n", (int)s.conflicts, s.conflicts /cpu_time);
printf("c decisions : %-12d (%4.2f %% random) (%.0f /sec)\n", (int)s.decisions, (float)s.rnd_decisions*100 / (float)s.decisions, s.decisions /cpu_time);
printf("c propagations : %-12d (%.0f /sec)\n", (int)s.propagations, s.propagations/cpu_time);
printf("c conflict literals : %-12d (%4.2f %% deleted)\n", (int)s.tot_literals, (s.max_literals - s.tot_literals)*100 / (double)s.max_literals);
printf("c nb reduced Clauses : %-12d\n", (int)s.nbReducedClauses);
if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used);
//printf("c CPU time : %.2f sec\n", cpu_time);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars )
{
abctime clk = Abc_Clock();
SimpSolver S;
S.verbosity = pPars->verb;
S.setConfBudget( pPars->nConfls > 0 ? (int64_t)pPars->nConfls : -1 );
gzFile in = gzopen(pFilename, "rb");
parse_DIMACS(in, S);
gzclose(in);
printf("c ============================[ Problem Statistics ]=============================\n");
printf("c | |\n");
printf("c | Number of variables: %12d |\n", S.nVars());
printf("c | Number of clauses: %12d |\n", S.nClauses());
if ( pPars->pre ) S.eliminate(true);
vec<Lit> dummy;
lbool ret = S.solveLimited(dummy);
if ( pPars->verb ) glucose_print_stats(S, Abc_Clock() - clk);
printf(ret == l_True ? "SATISFIABLE" : ret == l_False ? "UNSATISFIABLE" : "INDETERMINATE");
Abc_PrintTime( 1, " Time", Abc_Clock() - clk );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Glucose_SolverFromAig( Gia_Man_t * p, SimpSolver& S )
{
abctime clk = Abc_Clock();
int * pLit, * pStop, i;
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8 /*nLutSize*/, 0 /*fCnfObjIds*/, 1/*fAddOrCla*/, 0, 0/*verbose*/ );
for ( i = 0; i < pCnf->nClauses; i++ )
{
vec<Lit> lits;
for ( pLit = pCnf->pClauses[i], pStop = pCnf->pClauses[i+1]; pLit < pStop; pLit++ )
{
int Lit = *pLit;
int parsed_lit = (Lit & 1)? -(Lit >> 1)-1 : (Lit >> 1)+1;
int var = abs(parsed_lit)-1;
while (var >= S.nVars()) S.newVar();
lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) );
}
S.addClause(lits);
}
Vec_Int_t * vCnfIds = Vec_IntAllocArrayCopy(pCnf->pVarNums,pCnf->nVars);
//printf( "CNF stats: Vars = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals );
//Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
Cnf_DataFree(pCnf);
return vCnfIds;
}
int Glucose_SolveAig(Gia_Man_t * p, ExtSat_Pars * pPars)
{
abctime clk = Abc_Clock();
SimpSolver S;
S.verbosity = pPars->verb;
S.verbEveryConflicts = 50000;
S.showModel = false;
S.setConfBudget( pPars->nConfls > 0 ? (int64_t)pPars->nConfls : -1 );
S.parsing = 1;
Vec_Int_t * vCnfIds = Glucose_SolverFromAig(p,S);
S.parsing = 0;
if (pPars->verb)
{
printf("c ============================[ Problem Statistics ]=============================\n");
printf("c | |\n");
printf("c | Number of variables: %12d |\n", S.nVars());
printf("c | Number of clauses: %12d |\n", S.nClauses());
}
if (pPars->pre)
S.eliminate(true);
vec<Lit> dummy;
lbool ret = S.solveLimited(dummy);
if ( pPars->verb ) glucose_print_stats(S, Abc_Clock() - clk);
printf(ret == l_True ? "SATISFIABLE" : ret == l_False ? "UNSATISFIABLE" : "INDETERMINATE");
Abc_PrintTime( 1, " Time", Abc_Clock() - clk );
// port counterexample
if (ret == l_True)
{
Gia_Obj_t * pObj; int i;
p->pCexComb = Abc_CexAlloc(0,Gia_ManCiNum(p),1);
Gia_ManForEachCi( p, pObj, i )
{
assert(Vec_IntEntry(vCnfIds,Gia_ObjId(p, pObj))!=-1);
if (S.model[Vec_IntEntry(vCnfIds,Gia_ObjId(p, pObj))] == l_True)
Abc_InfoSetBit( p->pCexComb->pData, i);
}
}
Vec_IntFree(vCnfIds);
return (ret == l_True ? 10 : ret == l_False ? 20 : 0);
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
}
ABC_NAMESPACE_IMPL_END
/**CFile****************************************************************
FileName [AbcGlucose.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT solver Glucose 3.0.]
Synopsis [Interface to Glucose.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 6, 2017.]
Revision [$Id: AbcGlucose.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef SRC_EXTSAT_GLUCOSE_ABC_H_
#define SRC_EXTSAT_GLUCOSE_ABC_H_
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "aig/gia/gia.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_HEADER_START
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct ExtSat_Pars_ ExtSat_Pars;
struct ExtSat_Pars_ {
int pre; // preprocessing
int verb; // verbosity
int cust; // customizable
int nConfls; // conflict limit (0 = no limit)
};
static inline ExtSat_Pars ExtSat_CreatePars(int p, int v, int c, int nConfls)
{
ExtSat_Pars pars;
pars.pre = p;
pars.verb = v;
pars.cust = c;
pars.nConfls = nConfls;
return pars;
}
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
extern void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars );
extern int Glucose_SolveAig( Gia_Man_t * p, ExtSat_Pars * pPars );
ABC_NAMESPACE_HEADER_END
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [AbcGlucoseCmd.cpp]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT solver Glucose 3.0.]
Synopsis [Interface to Glucose.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 6, 2017.]
Revision [$Id: AbcGlucoseCmd.cpp,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig/gia/gia.h"
#include "base/main/mainInt.h"
#include "sat/glucose/AbcGlucose.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
extern "C" {
void Glucose_Init(Abc_Frame_t *pAbc)
{
Cmd_CommandAdd( pAbc, "ABC9", "&glucose", Abc_CommandGlucose, 0 );
}
void Glucose_End( Abc_Frame_t * pAbc )
{
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars );
extern int Glucose_SolveAig( Gia_Man_t * p, ExtSat_Pars * pPars );
int c = 0;
int pre = 1;
int verb = 0;
int nConfls = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Cpvh" ) ) != EOF )
{
switch ( c )
{
case 'C':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
goto usage;
}
nConfls = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nConfls < 0 )
goto usage;
break;
case 'p':
pre ^= 1;
break;
case 'v':
verb ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
ExtSat_Pars pPars = ExtSat_CreatePars(pre,verb,0,nConfls);
if ( argc == globalUtilOptind + 1 )
{
Glucose_SolveCnf( argv[globalUtilOptind], &pPars );
return 0;
}
if ( pAbc->pGia == NULL )
{
Abc_Print( -1, "Abc_CommandGlucose(): There is no AIG.\n" );
return 1;
}
if ( Glucose_SolveAig( pAbc->pGia, &pPars ) == 10 )
Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
return 0;
usage:
Abc_Print( -2, "usage: &glucose [-C num] [-pvh] <file.cnf>\n" );
Abc_Print( -2, "\t run glucose\n" );
Abc_Print( -2, "\t-C num : conflict limit [default = %d]\n", nConfls );
Abc_Print( -2, "\t-p : enable preprocessing [default = %d]\n",pre);
Abc_Print( -2, "\t-v : verbosity [default = %d]\n",verb);
Abc_Print( -2, "\t-h : print the command usage\n");
Abc_Print( -2, "\t<file.cnf> : (optional) CNF file to solve\n");
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
/*******************************************************************************************[Alg.h]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_Alg_h
#define Glucose_Alg_h
#include "sat/glucose/Vec.h"
namespace Glucose {
//=================================================================================================
// Useful functions on vector-like types:
//=================================================================================================
// Removing and searching for elements:
//
template<class V, class T>
static inline void remove(V& ts, const T& t)
{
int j = 0;
for (; j < ts.size() && ts[j] != t; j++);
assert(j < ts.size());
for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
ts.pop();
}
template<class V, class T>
static inline bool find(V& ts, const T& t)
{
int j = 0;
for (; j < ts.size() && ts[j] != t; j++);
return j < ts.size();
}
//=================================================================================================
// Copying vectors with support for nested vector types:
//
// Base case:
template<class T>
static inline void copy(const T& from, T& to)
{
to = from;
}
// Recursive case:
template<class T>
static inline void copy(const vec<T>& from, vec<T>& to, bool append = false)
{
if (!append)
to.clear();
for (int i = 0; i < from.size(); i++){
to.push();
copy(from[i], to.last());
}
}
template<class T>
static inline void append(const vec<T>& from, vec<T>& to){ copy(from, to, true); }
//=================================================================================================
}
#endif
/*****************************************************************************************[Alloc.h]
Copyright (c) 2008-2010, Niklas Sorensson
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 Glucose_Alloc_h
#define Glucose_Alloc_h
#include "sat/glucose/XAlloc.h"
#include "sat/glucose/Vec.h"
namespace Glucose {
//=================================================================================================
// Simple Region-based memory allocator:
template<class T>
class RegionAllocator
{
T* memory;
uint32_t sz;
uint32_t cap;
uint32_t wasted_;
void capacity(uint32_t min_cap);
public:
// TODO: make this a class for better type-checking?
typedef uint32_t Ref;
enum { Ref_Undef = UINT32_MAX };
enum { Unit_Size = sizeof(uint32_t) };
explicit RegionAllocator(uint32_t start_cap = 1024*1024) : memory(NULL), sz(0), cap(0), wasted_(0){ capacity(start_cap); }
~RegionAllocator()
{
if (memory != NULL)
::free(memory);
}
uint32_t size () const { return sz; }
uint32_t wasted () const { return wasted_; }
Ref alloc (int size);
void free_ (int size) { wasted_ += size; }
// Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
T& operator[](Ref r) { assert(r >= 0 && r < sz); return memory[r]; }
const T& operator[](Ref r) const { assert(r >= 0 && r < sz); return memory[r]; }
T* lea (Ref r) { assert(r >= 0 && r < sz); return &memory[r]; }
const T* lea (Ref r) const { assert(r >= 0 && r < sz); return &memory[r]; }
Ref ael (const T* t) { assert((void*)t >= (void*)&memory[0] && (void*)t < (void*)&memory[sz-1]);
return (Ref)(t - &memory[0]); }
void moveTo(RegionAllocator& to) {
if (to.memory != NULL) ::free(to.memory);
to.memory = memory;
to.sz = sz;
to.cap = cap;
to.wasted_ = wasted_;
memory = NULL;
sz = cap = wasted_ = 0;
}
};
template<class T>
void RegionAllocator<T>::capacity(uint32_t min_cap)
{
if (cap >= min_cap) return;
uint32_t prev_cap = cap;
while (cap < min_cap){
// NOTE: Multiply by a factor (13/8) without causing overflow, then add 2 and make the
// result even by clearing the least significant bit. The resulting sequence of capacities
// is carefully chosen to hit a maximum capacity that is close to the '2^32-1' limit when
// using 'uint32_t' as indices so that as much as possible of this space can be used.
uint32_t delta = ((cap >> 1) + (cap >> 3) + 2) & ~1;
cap += delta;
if (cap <= prev_cap)
throw OutOfMemoryException();
}
//printf(" .. (%p) cap = %u\n", this, cap);
assert(cap > 0);
memory = (T*)xrealloc(memory, sizeof(T)*cap);
}
template<class T>
typename RegionAllocator<T>::Ref
RegionAllocator<T>::alloc(int size)
{
//printf("ALLOC called (this = %p, size = %d)\n", this, size); fflush(stdout);
assert(size > 0);
capacity(sz + size);
uint32_t prev_sz = sz;
sz += size;
// Handle overflow:
if (sz < prev_sz)
throw OutOfMemoryException();
return prev_sz;
}
//=================================================================================================
}
#endif
/***********************************************************************************[BoundedQueue.h]
Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon
CRIL - Univ. Artois, France
LRI - Univ. Paris Sud, France
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
#include "sat/glucose/Vec.h"
//=================================================================================================
namespace Glucose {
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 !)
bool expComputed;
double exp,value;
public:
bqueue(void) : first(0), last(0), sumofqueue(0), maxsize(0), queuesize(0),expComputed(false) { }
void initSize(int size) {growTo(size);exp = 2.0/(size+1);} // Init size of bounded size queue
void push(T x) {
expComputed = false;
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;last = 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;}
unsigned int getavg() const {return (unsigned int)(sumofqueue/((uint64_t)queuesize));}
int maxSize() const {return maxsize;}
double getavgDouble() const {
double tmp = 0;
for(int i=0;i<elems.size();i++) {
tmp+=elems[i];
}
return tmp/elems.size();
}
int isvalid() const {return (queuesize==maxsize);}
void growTo(int size) {
elems.growTo(size);
first=0; maxsize=size; queuesize = 0;last = 0;
for(int i=0;i<size;i++) elems[i]=0;
}
double getAvgExp() {
if(expComputed) return value;
double a=exp;
value = elems[first];
for(int i = first;i<maxsize;i++) {
value+=a*((double)elems[i]);
a=a*exp;
}
for(int i = 0;i<last;i++) {
value+=a*((double)elems[i]);
a=a*exp;
}
value = value*(1-exp)/(1-a);
expComputed = true;
return value;
}
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
/************************************************************************************[Constants.h]
Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon
CRIL - Univ. Artois, France
LRI - Univ. Paris Sud, France
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.
**************************************************************************************************/
#define DYNAMICNBLEVEL
#define CONSTANTREMOVECLAUSE
#define UPDATEVARACTIVITY
// Constants for clauses reductions
#define RATIOREMOVECLAUSES 2
// Constants for restarts
#define LOWER_BOUND_FOR_BLOCKING_RESTART 10000
/****************************************************************************************[Dimacs.h]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_Dimacs_h
#define Glucose_Dimacs_h
#include <stdio.h>
#include "sat/glucose/ParseUtils.h"
#include "sat/glucose/SolverTypes.h"
namespace Glucose {
//=================================================================================================
// DIMACS Parser:
template<class B, class Solver>
static void readClause(B& in, Solver& S, vec<Lit>& lits) {
int parsed_lit, var;
lits.clear();
for (;;){
parsed_lit = parseInt(in);
if (parsed_lit == 0) break;
var = abs(parsed_lit)-1;
while (var >= S.nVars()) S.newVar();
lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) );
}
}
template<class B, class Solver>
static void parse_DIMACS_main(B& in, Solver& S) {
vec<Lit> lits;
int vars = 0;
int clauses = 0;
int cnt = 0;
for (;;){
skipWhitespace(in);
if (*in == EOF) break;
else if (*in == 'p'){
if (eagerMatch(in, "p cnf")){
vars = parseInt(in);
clauses = parseInt(in);
// SATRACE'06 hack
// if (clauses > 4000000)
// S.eliminate(true);
}else{
printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
}
} else if (*in == 'c' || *in == 'p')
skipLine(in);
else{
cnt++;
readClause(in, S, lits);
S.addClause_(lits); }
}
if (vars != S.nVars())
fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of variables.\n");
if (cnt != clauses)
fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of clauses.\n");
}
// Inserts problem into solver.
//
template<class Solver>
static void parse_DIMACS(gzFile input_stream, Solver& S) {
StreamBuffer in(input_stream);
parse_DIMACS_main(in, S); }
//=================================================================================================
}
#endif
/******************************************************************************************[Heap.h]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_Heap_h
#define Glucose_Heap_h
#include "sat/glucose/Vec.h"
namespace Glucose {
//=================================================================================================
// A heap implementation with support for decrease/increase key.
template<class Comp>
class Heap {
Comp lt; // The heap is a minimum-heap with respect to this comparator
vec<int> heap; // Heap of integers
vec<int> indices; // Each integers position (index) in the Heap
// Index "traversal" functions
static inline int left (int i) { return i*2+1; }
static inline int right (int i) { return (i+1)*2; }
static inline int parent(int i) { return (i-1) >> 1; }
void percolateUp(int i)
{
int x = heap[i];
int p = parent(i);
while (i != 0 && lt(x, heap[p])){
heap[i] = heap[p];
indices[heap[p]] = i;
i = p;
p = parent(p);
}
heap [i] = x;
indices[x] = i;
}
void percolateDown(int i)
{
int x = heap[i];
while (left(i) < heap.size()){
int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
if (!lt(heap[child], x)) break;
heap[i] = heap[child];
indices[heap[i]] = i;
i = child;
}
heap [i] = x;
indices[x] = i;
}
public:
Heap(const Comp& c) : lt(c) { }
int size () const { return heap.size(); }
bool empty () const { return heap.size() == 0; }
bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; }
int operator[](int index) const { assert(index < heap.size()); return heap[index]; }
void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); }
void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
// Safe variant of insert/decrease/increase:
void update(int n)
{
if (!inHeap(n))
insert(n);
else {
percolateUp(indices[n]);
percolateDown(indices[n]); }
}
void insert(int n)
{
indices.growTo(n+1, -1);
assert(!inHeap(n));
indices[n] = heap.size();
heap.push(n);
percolateUp(indices[n]);
}
int removeMin()
{
int x = heap[0];
heap[0] = heap.last();
indices[heap[0]] = 0;
indices[x] = -1;
heap.pop();
if (heap.size() > 1) percolateDown(0);
return x;
}
// Rebuild the heap from scratch, using the elements in 'ns':
void build(vec<int>& ns) {
int i;
for (i = 0; i < heap.size(); i++)
indices[heap[i]] = -1;
heap.clear();
for (i = 0; i < ns.size(); i++){
indices[ns[i]] = i;
heap.push(ns[i]); }
for (i = heap.size() / 2 - 1; i >= 0; i--)
percolateDown(i);
}
void clear(bool dealloc = false)
{
int i;
for (i = 0; i < heap.size(); i++)
indices[heap[i]] = -1;
heap.clear(dealloc);
}
};
//=================================================================================================
}
#endif
/**************************************************************************************[IntTypes.h]
Copyright (c) 2009-2010, Niklas Sorensson
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 Glucose_IntTypes_h
#define Glucose_IntTypes_h
#ifdef __sun
// Not sure if there are newer versions that support C99 headers. The
// needed features are implemented in the headers below though:
# include <sys/int_types.h>
# include <sys/int_fmtio.h>
# include <sys/int_limits.h>
#else
#define __STDC_LIMIT_MACROS
# include "pstdint.h"
//# include <inttypes.h>
#endif
#include <limits.h>
#ifndef PRIu64
#define PRIu64 "lu"
#define PRIi64 "ld"
#endif
//=================================================================================================
#endif
/*******************************************************************************************[Map.h]
Copyright (c) 2006-2010, Niklas Sorensson
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 Glucose_Map_h
#define Glucose_Map_h
#include "sat/glucose/IntTypes.h"
#include "sat/glucose/Vec.h"
namespace Glucose {
//=================================================================================================
// Default hash/equals functions
//
template<class K> struct Hash { uint32_t operator()(const K& k) const { return hash(k); } };
template<class K> struct Equal { bool operator()(const K& k1, const K& k2) const { return k1 == k2; } };
template<class K> struct DeepHash { uint32_t operator()(const K* k) const { return hash(*k); } };
template<class K> struct DeepEqual { bool operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
static inline uint32_t hash(uint32_t x){ return x; }
static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
//=================================================================================================
// Some primes
//
static const int nprimes = 25;
static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 };
//=================================================================================================
// Hash table implementation of Maps
//
template<class K, class D, class H = Hash<K>, class E = Equal<K> >
class Map {
public:
struct Pair { K key; D data; };
private:
H hash;
E equals;
vec<Pair>* table;
int cap;
int size;
// Don't allow copying (error prone):
Map<K,D,H,E>& operator = (Map<K,D,H,E>& other) { assert(0); }
Map (Map<K,D,H,E>& other) { assert(0); }
bool checkCap(int new_size) const { return new_size > cap; }
int32_t index (const K& k) const { return hash(k) % cap; }
void _insert (const K& k, const D& d) {
vec<Pair>& ps = table[index(k)];
ps.push(); ps.last().key = k; ps.last().data = d; }
void rehash () {
const vec<Pair>* old = table;
int old_cap = cap;
int newsize = primes[0];
for (int i = 1; newsize <= cap && i < nprimes; i++)
newsize = primes[i];
table = new vec<Pair>[newsize];
cap = newsize;
for (int i = 0; i < old_cap; i++){
for (int j = 0; j < old[i].size(); j++){
_insert(old[i][j].key, old[i][j].data); }}
delete [] old;
// printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize);
}
public:
Map () : table(NULL), cap(0), size(0) {}
Map (const H& h, const E& e) : hash(h), equals(e), table(NULL), cap(0), size(0){}
~Map () { delete [] table; }
// PRECONDITION: the key must already exist in the map.
const D& operator [] (const K& k) const
{
assert(size != 0);
const D* res = NULL;
const vec<Pair>& ps = table[index(k)];
for (int i = 0; i < ps.size(); i++)
if (equals(ps[i].key, k))
res = &ps[i].data;
assert(res != NULL);
return *res;
}
// PRECONDITION: the key must already exist in the map.
D& operator [] (const K& k)
{
assert(size != 0);
D* res = NULL;
vec<Pair>& ps = table[index(k)];
for (int i = 0; i < ps.size(); i++)
if (equals(ps[i].key, k))
res = &ps[i].data;
assert(res != NULL);
return *res;
}
// PRECONDITION: the key must *NOT* exist in the map.
void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; }
bool peek (const K& k, D& d) const {
if (size == 0) return false;
const vec<Pair>& ps = table[index(k)];
for (int i = 0; i < ps.size(); i++)
if (equals(ps[i].key, k)){
d = ps[i].data;
return true; }
return false;
}
bool has (const K& k) const {
if (size == 0) return false;
const vec<Pair>& ps = table[index(k)];
for (int i = 0; i < ps.size(); i++)
if (equals(ps[i].key, k))
return true;
return false;
}
// PRECONDITION: the key must exist in the map.
void remove(const K& k) {
assert(table != NULL);
vec<Pair>& ps = table[index(k)];
int j = 0;
for (; j < ps.size() && !equals(ps[j].key, k); j++);
assert(j < ps.size());
ps[j] = ps.last();
ps.pop();
size--;
}
void clear () {
cap = size = 0;
delete [] table;
table = NULL;
}
int elems() const { return size; }
int bucket_count() const { return cap; }
// NOTE: the hash and equality objects are not moved by this method:
void moveTo(Map& other){
delete [] other.table;
other.table = table;
other.cap = cap;
other.size = size;
table = NULL;
size = cap = 0;
}
// NOTE: given a bit more time, I could make a more C++-style iterator out of this:
const vec<Pair>& bucket(int i) const { return table[i]; }
};
//=================================================================================================
}
#endif
/**************************************************************************************[Options.cc]
Copyright (c) 2008-2010, Niklas Sorensson
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 "sat/glucose/Sort.h"
#include "sat/glucose/Options.h"
#include "sat/glucose/ParseUtils.h"
using namespace Glucose;
void Glucose::parseOptions(int& argc, char** argv, bool strict)
{
int i, j;
for (i = j = 1; i < argc; i++){
const char* str = argv[i];
if (match(str, "--") && match(str, Option::getHelpPrefixString()) && match(str, "help")){
if (*str == '\0')
printUsageAndExit(argc, argv);
else if (match(str, "-verb"))
printUsageAndExit(argc, argv, true);
} else {
bool parsed_ok = false;
for (int k = 0; !parsed_ok && k < Option::getOptionList().size(); k++){
parsed_ok = Option::getOptionList()[k]->parse(argv[i]);
// fprintf(stderr, "checking %d: %s against flag <%s> (%s)\n", i, argv[i], Option::getOptionList()[k]->name, parsed_ok ? "ok" : "skip");
}
if (!parsed_ok)
if (strict && match(argv[i], "-"))
fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()), exit(1);
else
argv[j++] = argv[i];
}
}
argc -= (i - j);
}
void Glucose::setUsageHelp (const char* str){ Option::getUsageString() = str; }
void Glucose::setHelpPrefixStr (const char* str){ Option::getHelpPrefixString() = str; }
void Glucose::printUsageAndExit (int argc, char** argv, bool verbose)
{
const char* usage = Option::getUsageString();
if (usage != NULL)
fprintf(stderr, usage, argv[0]);
sort(Option::getOptionList(), Option::OptionLt());
const char* prev_cat = NULL;
const char* prev_type = NULL;
for (int i = 0; i < Option::getOptionList().size(); i++){
const char* cat = Option::getOptionList()[i]->category;
const char* type = Option::getOptionList()[i]->type_name;
if (cat != prev_cat)
fprintf(stderr, "\n%s OPTIONS:\n\n", cat);
else if (type != prev_type)
fprintf(stderr, "\n");
Option::getOptionList()[i]->help(verbose);
prev_cat = Option::getOptionList()[i]->category;
prev_type = Option::getOptionList()[i]->type_name;
}
fprintf(stderr, "\nHELP OPTIONS:\n\n");
fprintf(stderr, " --%shelp Print help message.\n", Option::getHelpPrefixString());
fprintf(stderr, " --%shelp-verb Print verbose help message.\n", Option::getHelpPrefixString());
fprintf(stderr, "\n");
exit(0);
}
/************************************************************************************[ParseUtils.h]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_ParseUtils_h
#define Glucose_ParseUtils_h
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "misc/zlib/zlib.h"
namespace Glucose {
//-------------------------------------------------------------------------------------------------
// A simple buffered character stream class:
static const int buffer_size = 1048576;
class StreamBuffer {
gzFile in;
unsigned char buf[buffer_size];
int pos;
int size;
void assureLookahead() {
if (pos >= size) {
pos = 0;
size = gzread(in, buf, sizeof(buf)); } }
public:
explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0) { assureLookahead(); }
int operator * () const { return (pos >= size) ? EOF : buf[pos]; }
void operator ++ () { pos++; assureLookahead(); }
int position () const { return pos; }
};
//-------------------------------------------------------------------------------------------------
// End-of-file detection functions for StreamBuffer and char*:
static inline bool isEof(StreamBuffer& in) { return *in == EOF; }
static inline bool isEof(const char* in) { return *in == '\0'; }
//-------------------------------------------------------------------------------------------------
// Generic parse functions parametrized over the input-stream type.
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 (isEof(in)) return;
if (*in == '\n') { ++in; return; }
++in; } }
template<class B>
static double parseDouble(B& in) { // only in the form X.XXXXXe-XX
bool neg= false;
double accu = 0.0;
double currentExponent = 1;
int exponent;
skipWhitespace(in);
if(*in == EOF) return 0;
if (*in == '-') neg = true, ++in;
else if (*in == '+') ++in;
if (*in < '1' || *in > '9') printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
accu = (double)(*in - '0');
++in;
if (*in != '.') printf("PARSE ERROR! Unexpected char: %c\n", *in),exit(3);
++in; // skip dot
currentExponent = 0.1;
while (*in >= '0' && *in <= '9')
accu = accu + currentExponent * ((double)(*in - '0')),
currentExponent /= 10,
++in;
if (*in != 'e') printf("PARSE ERROR! Unexpected char: %c\n", *in),exit(3);
++in; // skip dot
exponent = parseInt(in); // read exponent
accu *= pow(10,exponent);
return neg ? -accu:accu;
}
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') fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
while (*in >= '0' && *in <= '9')
val = val*10 + (*in - '0'),
++in;
return neg ? -val : val; }
// String matching: in case of a match the input iterator will be advanced the corresponding
// number of characters.
template<class B>
static bool match(B& in, const char* str) {
int i;
for (i = 0; str[i] != '\0'; i++)
if (in[i] != str[i])
return false;
in += i;
return true;
}
// String matching: consumes characters eagerly, but does not require random access iterator.
template<class B>
static bool eagerMatch(B& in, const char* str) {
for (; *str != '\0'; ++str, ++in)
if (*str != *in)
return false;
return true; }
//=================================================================================================
}
#endif
/*****************************************************************************************[Queue.h]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_Queue_h
#define Glucose_Queue_h
#include "sat/glucose/Vec.h"
namespace Glucose {
//=================================================================================================
template<class T>
class Queue {
vec<T> buf;
int first;
int end;
public:
typedef T Key;
Queue() : buf(1), first(0), end(0) {}
void clear (bool dealloc = false) { buf.clear(dealloc); buf.growTo(1); first = end = 0; }
int size () const { return (end >= first) ? end - first : end - first + buf.size(); }
const T& operator [] (int index) const { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
T& operator [] (int index) { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
T peek () const { assert(first != end); return buf[first]; }
void pop () { assert(first != end); first++; if (first == buf.size()) first = 0; }
void insert(T elem) { // INVARIANT: buf[end] is always unused
buf[end++] = elem;
if (end == buf.size()) end = 0;
if (first == end){ // Resize:
vec<T> tmp((buf.size()*3 + 1) >> 1);
//**/printf("queue alloc: %d elems (%.1f MB)\n", tmp.size(), tmp.size() * sizeof(T) / 1000000.0);
int j, i = 0;
for (j = first; j < buf.size(); j++) tmp[i++] = buf[j];
for (j = 0 ; j < end ; j++) tmp[i++] = buf[j];
first = 0;
end = buf.size();
tmp.moveTo(buf);
}
}
};
//=================================================================================================
}
#endif
/************************************************************************************[SimpSolver.h]
Copyright (c) 2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_SimpSolver_h
#define Glucose_SimpSolver_h
#include "sat/glucose/Queue.h"
#include "sat/glucose/Solver.h"
namespace Glucose {
//=================================================================================================
class SimpSolver : public Solver {
public:
// Constructor/Destructor:
//
SimpSolver();
~SimpSolver();
// Problem specification:
//
Var newVar (bool polarity = true, bool dvar = true);
bool addClause (const vec<Lit>& ps);
bool addEmptyClause(); // Add the empty clause to the solver.
bool addClause (Lit p); // Add a unit clause to the solver.
bool addClause (Lit p, Lit q); // Add a binary clause to the solver.
bool addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
bool addClause_( vec<Lit>& ps);
bool substitute(Var v, Lit x); // Replace all occurences of v with x (may cause a contradiction).
// Variable mode:
//
void setFrozen (Var v, bool b); // If a variable is frozen it will not be eliminated.
bool isEliminated(Var v) const;
// Solving:
//
bool solve (const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
lbool solveLimited(const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
bool solve ( bool do_simp = true, bool turn_off_simp = false);
bool solve (Lit p , bool do_simp = true, bool turn_off_simp = false);
bool solve (Lit p, Lit q, bool do_simp = true, bool turn_off_simp = false);
bool solve (Lit p, Lit q, Lit r, bool do_simp = true, bool turn_off_simp = false);
bool eliminate (bool turn_off_elim = false); // Perform variable elimination based simplification.
// Memory managment:
//
virtual void garbageCollect();
// Generate a (possibly simplified) DIMACS file:
//
#if 0
void toDimacs (const char* file, const vec<Lit>& assumps);
void toDimacs (const char* file);
void toDimacs (const char* file, Lit p);
void toDimacs (const char* file, Lit p, Lit q);
void toDimacs (const char* file, Lit p, Lit q, Lit r);
#endif
// Mode of operation:
//
int parsing;
int grow; // Allow a variable elimination step to grow by a number of clauses (default to zero).
int clause_lim; // Variables are not eliminated if it produces a resolvent with a length above this limit.
// -1 means no limit.
int subsumption_lim; // Do not check if subsumption against a clause larger than this. -1 means no limit.
double simp_garbage_frac; // A different limit for when to issue a GC during simplification (Also see 'garbage_frac').
bool use_asymm; // Shrink clauses by asymmetric branching.
bool use_rcheck; // Check if a clause is already implied. Prett costly, and subsumes subsumptions :)
bool use_elim; // Perform variable elimination.
// Statistics:
//
int merges;
int asymm_lits;
int eliminated_vars;
protected:
// Helper structures:
//
struct ElimLt {
const vec<int>& n_occ;
explicit ElimLt(const vec<int>& no) : n_occ(no) {}
// TODO: are 64-bit operations here noticably bad on 32-bit platforms? Could use a saturating
// 32-bit implementation instead then, but this will have to do for now.
uint64_t cost (Var x) const { return (uint64_t)n_occ[toInt(mkLit(x))] * (uint64_t)n_occ[toInt(~mkLit(x))]; }
bool operator()(Var x, Var y) const { return cost(x) < cost(y); }
// TODO: investigate this order alternative more.
// bool operator()(Var x, Var y) const {
// int c_x = cost(x);
// int c_y = cost(y);
// return c_x < c_y || c_x == c_y && x < y; }
};
struct ClauseDeleted {
const ClauseAllocator& ca;
explicit ClauseDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
bool operator()(const CRef& cr) const { return ca[cr].mark() == 1; } };
// Solver state:
//
int elimorder;
bool use_simplification;
vec<uint32_t> elimclauses;
vec<char> touched;
OccLists<Var, vec<CRef>, ClauseDeleted>
occurs;
vec<int> n_occ;
Heap<ElimLt> elim_heap;
Queue<CRef> subsumption_queue;
vec<char> frozen;
vec<char> eliminated;
int bwdsub_assigns;
int n_touched;
// Temporaries:
//
CRef bwdsub_tmpunit;
// Main internal methods:
//
lbool solve_ (bool do_simp = true, bool turn_off_simp = false);
bool asymm (Var v, CRef cr);
bool asymmVar (Var v);
void updateElimHeap (Var v);
void gatherTouchedClauses ();
bool merge (const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause);
bool merge (const Clause& _ps, const Clause& _qs, Var v, int& size);
bool backwardSubsumptionCheck (bool verbose = false);
bool eliminateVar (Var v);
void extendModel ();
void removeClause (CRef cr);
bool strengthenClause (CRef cr, Lit l);
void cleanUpClauses ();
bool implied (const vec<Lit>& c);
void relocAll (ClauseAllocator& to);
};
//=================================================================================================
// Implementation of inline methods:
inline bool SimpSolver::isEliminated (Var v) const { return eliminated[v] != 0; }
inline void SimpSolver::updateElimHeap(Var v) {
assert(use_simplification);
// if (!frozen[v] && !isEliminated(v) && value(v) == l_Undef)
if (elim_heap.inHeap(v) || (!frozen[v] && !isEliminated(v) && value(v) == l_Undef))
elim_heap.update(v); }
inline bool SimpSolver::addClause (const vec<Lit>& ps) { ps.copyTo(add_tmp); return addClause_(add_tmp); }
inline bool SimpSolver::addEmptyClause() { add_tmp.clear(); return addClause_(add_tmp); }
inline bool SimpSolver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
inline bool SimpSolver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
inline bool SimpSolver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
inline void SimpSolver::setFrozen (Var v, bool b) { frozen[v] = (char)b; if (use_simplification && !b) { updateElimHeap(v); } }
inline bool SimpSolver::solve ( bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); return solve_(do_simp, turn_off_simp) == l_True; }
inline bool SimpSolver::solve (Lit p , bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_(do_simp, turn_off_simp) == l_True; }
inline bool SimpSolver::solve (Lit p, Lit q, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_(do_simp, turn_off_simp) == l_True; }
inline bool SimpSolver::solve (Lit p, Lit q, Lit r, bool do_simp, bool turn_off_simp) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_(do_simp, turn_off_simp) == l_True; }
inline bool SimpSolver::solve (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
budgetOff(); assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp) == l_True; }
inline lbool SimpSolver::solveLimited (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp); }
//=================================================================================================
}
#endif
/******************************************************************************************[Sort.h]
Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_Sort_h
#define Glucose_Sort_h
#include "sat/glucose/Vec.h"
//=================================================================================================
// Some sorting algorithms for vec's
namespace Glucose {
template<class T>
struct LessThan_default {
bool operator () (T x, T y) { return x < y; }
};
template <class T, class LessThan>
void selectionSort(T* array, int size, LessThan lt)
{
int i, j, best_i;
T tmp;
for (i = 0; i < size-1; i++){
best_i = i;
for (j = i+1; j < size; j++){
if (lt(array[j], array[best_i]))
best_i = j;
}
tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
}
}
template <class T> static inline void selectionSort(T* array, int size) {
selectionSort(array, size, LessThan_default<T>()); }
template <class T, class LessThan>
void sort(T* array, int size, LessThan lt)
{
if (size <= 15)
selectionSort(array, size, lt);
else{
T pivot = array[size / 2];
T tmp;
int i = -1;
int j = size;
for(;;){
do i++; while(lt(array[i], pivot));
do j--; while(lt(pivot, array[j]));
if (i >= j) break;
tmp = array[i]; array[i] = array[j]; array[j] = tmp;
}
sort(array , i , lt);
sort(&array[i], size-i, lt);
}
}
template <class T> static inline void sort(T* array, int size) {
sort(array, size, LessThan_default<T>()); }
//=================================================================================================
// For 'vec's:
template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
sort((T*)v, v.size(), lt); }
template <class T> void sort(vec<T>& v) {
sort(v, LessThan_default<T>()); }
//=================================================================================================
}
#endif
/***************************************************************************************[System.cc]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 "sat/glucose/System.h"
#if defined(__linux__)
#include <stdio.h>
#include <stdlib.h>
using namespace Glucose;
// TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and
// one for reading the current virtual memory size.
static inline int memReadStat(int field)
{
char name[256];
pid_t pid = getpid();
int value;
sprintf(name, "/proc/%d/statm", pid);
FILE* in = fopen(name, "rb");
if (in == NULL) return 0;
for (; field >= 0; field--)
if (fscanf(in, "%d", &value) != 1)
printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1);
fclose(in);
return value;
}
static inline int memReadPeak(void)
{
char name[256];
pid_t pid = getpid();
sprintf(name, "/proc/%d/status", pid);
FILE* in = fopen(name, "rb");
if (in == NULL) return 0;
// Find the correct line, beginning with "VmPeak:":
int peak_kb = 0;
while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1)
while (!feof(in) && fgetc(in) != '\n')
;
fclose(in);
return peak_kb;
}
double Glucose::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); }
double Glucose::memUsedPeak() {
double peak = memReadPeak() / 1024;
return peak == 0 ? memUsed() : peak; }
#elif defined(__FreeBSD__)
double Glucose::memUsed(void) {
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
return (double)ru.ru_maxrss / 1024; }
double MiniSat::memUsedPeak(void) { return memUsed(); }
#elif defined(__APPLE__)
#include <malloc/malloc.h>
double Glucose::memUsed(void) {
malloc_statistics_t t;
malloc_zone_statistics(NULL, &t);
return (double)t.max_size_in_use / (1024*1024); }
#else
double Glucose::memUsed() {
return 0; }
#endif
/****************************************************************************************[System.h]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_System_h
#define Glucose_System_h
#if defined(__linux__)
#include <fpu_control.h>
#endif
#include "sat/glucose/IntTypes.h"
//-------------------------------------------------------------------------------------------------
namespace Glucose {
static inline double cpuTime(void); // CPU-time in seconds.
extern double memUsed(); // Memory in mega bytes (returns 0 for unsupported architectures).
extern double memUsedPeak(); // Peak-memory in mega bytes (returns 0 for unsupported architectures).
}
//-------------------------------------------------------------------------------------------------
// Implementation of inline functions:
#if defined(_MSC_VER) || defined(__MINGW32__)
#include <time.h>
static inline double Glucose::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; }
#else
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
static inline double Glucose::cpuTime(void) {
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);
return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
#endif
#endif
/*******************************************************************************************[Vec.h]
Copyright (c) 2003-2007, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
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 Glucose_Vec_h
#define Glucose_Vec_h
#include <assert.h>
#include <new>
#include "sat/glucose/IntTypes.h"
#include "sat/glucose/XAlloc.h"
namespace Glucose {
//=================================================================================================
// Automatically resizable arrays
//
// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
template<class T>
class vec {
T* data;
int sz;
int cap;
// Don't allow copying (error prone):
vec<T>& operator = (vec<T>& other) { assert(0); return *this; }
vec (vec<T>& other) { assert(0); }
// Helpers for calculating next capacity:
static inline int imax (int x, int y) { int mask = (y-x) >> (sizeof(int)*8-1); return (x&mask) + (y&(~mask)); }
//static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
public:
// Constructors:
vec() : data(NULL) , sz(0) , cap(0) { }
explicit vec(int size) : data(NULL) , sz(0) , cap(0) { growTo(size); }
vec(int size, const T& pad) : data(NULL) , sz(0) , cap(0) { growTo(size, pad); }
~vec() { clear(true); }
// Pointer to first element:
operator T* (void) { return data; }
// Size operations:
int size (void) const { return sz; }
void shrink (int nelems) { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }
void shrink_ (int nelems) { assert(nelems <= sz); sz -= nelems; }
int capacity (void) const { return cap; }
void capacity (int min_cap);
void growTo (int size);
void growTo (int size, const T& pad);
void clear (bool dealloc = false);
// Stack interface:
void push (void) { if (sz == cap) capacity(sz+1); new (&data[sz]) T(); sz++; }
void push (const T& elem) { if (sz == cap) capacity(sz+1); data[sz++] = elem; }
void push_ (const T& elem) { assert(sz < cap); data[sz++] = elem; }
void pop (void) { assert(sz > 0); sz--, data[sz].~T(); }
// NOTE: it seems possible that overflow can happen in the 'sz+1' expression of 'push()', but
// in fact it can not since it requires that 'cap' is equal to INT_MAX. This in turn can not
// happen given the way capacities are calculated (below). Essentially, all capacities are
// even, but INT_MAX is odd.
const T& last (void) const { return data[sz-1]; }
T& last (void) { return data[sz-1]; }
// Vector interface:
const T& operator [] (int index) const { return data[index]; }
T& operator [] (int index) { return data[index]; }
// Duplicatation (preferred instead):
void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
};
template<class T>
void vec<T>::capacity(int min_cap) {
if (cap >= min_cap) return;
int add = imax((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1); // NOTE: grow by approximately 3/2
if (add > INT_MAX - cap || ((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM)
throw OutOfMemoryException();
}
template<class T>
void vec<T>::growTo(int size, const T& pad) {
if (sz >= size) return;
capacity(size);
for (int i = sz; i < size; i++) data[i] = pad;
sz = size; }
template<class T>
void vec<T>::growTo(int size) {
if (sz >= size) return;
capacity(size);
for (int i = sz; i < size; i++) new (&data[i]) T();
sz = size; }
template<class T>
void vec<T>::clear(bool dealloc) {
if (data != NULL){
for (int i = 0; i < sz; i++) data[i].~T();
sz = 0;
if (dealloc) free(data), data = NULL, cap = 0; } }
//=================================================================================================
}
#endif
/****************************************************************************************[XAlloc.h]
Copyright (c) 2009-2010, Niklas Sorensson
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 Glucose_XAlloc_h
#define Glucose_XAlloc_h
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
namespace Glucose {
//=================================================================================================
// Simple layer on top of malloc/realloc to catch out-of-memory situtaions and provide some typing:
class OutOfMemoryException{};
static inline void* xrealloc(void *ptr, size_t size)
{
void* mem = realloc(ptr, size);
if (mem == NULL && errno == ENOMEM){
throw OutOfMemoryException();
}else {
return mem;
}
}
//=================================================================================================
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment