From 67b192350ef1d6c6d6e433c1ddd1ac1e63b9f480 Mon Sep 17 00:00:00 2001 From: audemard Date: Tue, 9 May 2023 11:30:58 +0200 Subject: [PATCH] Glucose 3.0 --- README.md | 10 +- build.sh | 11 - clean.sh | 11 - {sources/glucose/core => core}/BoundedQueue.h | 6 +- {sources/glucose/core => core}/Constants.h | 0 {sources/glucose/core => core}/Dimacs.h | 6 +- {sources/glucose/core => core}/Main.cc | 54 +- {sources/glucose/core => core}/Makefile | 0 {sources/glucose/core => core}/Solver.cc | 531 +++++--- {sources/glucose/core => core}/Solver.h | 65 +- {sources/glucose/core => core}/SolverTypes.h | 22 +- glucose.sh | 58 - {sources/glucose/mtl => mtl}/Alg.h | 6 +- {sources/glucose/mtl => mtl}/Alloc.h | 6 +- {sources/glucose/mtl => mtl}/Heap.h | 6 +- {sources/glucose/mtl => mtl}/IntTypes.h | 4 +- {sources/glucose/mtl => mtl}/Map.h | 6 +- {sources/glucose/mtl => mtl}/Queue.h | 6 +- {sources/glucose/mtl => mtl}/Sort.h | 6 +- {sources/glucose/mtl => mtl}/Vec.h | 6 +- {sources/glucose/mtl => mtl}/XAlloc.h | 6 +- {sources/glucose/mtl => mtl}/config.mk | 0 {sources/glucose/mtl => mtl}/template.mk | 2 +- {sources/glucose/simp => simp}/Main.cc | 110 +- {sources/glucose/simp => simp}/Makefile | 3 +- {sources/glucose/simp => simp}/SimpSolver.cc | 48 +- {sources/glucose/simp => simp}/SimpSolver.h | 7 +- sources/SatElite/ForMani/ADTs/FSet.h | 50 - sources/SatElite/ForMani/ADTs/File.C | 154 --- sources/SatElite/ForMani/ADTs/File.h | 134 -- sources/SatElite/ForMani/ADTs/File.od | Bin 29828 -> 0 bytes sources/SatElite/ForMani/ADTs/File.or | Bin 7524 -> 0 bytes sources/SatElite/ForMani/ADTs/Hash_standard.h | 82 -- sources/SatElite/ForMani/ADTs/Makefile | 4 - sources/SatElite/ForMani/ADTs/Map.h | 252 ---- sources/SatElite/ForMani/ADTs/Set.h | 236 ---- sources/SatElite/ForMani/ADTs/Sort.h | 124 -- sources/SatElite/ForMani/ADTs/StackAlloc.h | 67 - sources/SatElite/ForMani/ADTs/VecAlloc.h | 75 -- sources/SatElite/ForMani/ADTs/VecMaps.h | 93 -- sources/SatElite/ForMani/ADTs/depend.mak | 65 - sources/SatElite/ForMani/Global/Global.C | 291 ----- sources/SatElite/ForMani/Global/Global.h | 481 ------- sources/SatElite/ForMani/Global/Global.od | Bin 41896 -> 0 bytes sources/SatElite/ForMani/Global/Global.or | Bin 13264 -> 0 bytes sources/SatElite/ForMani/Global/Makefile | 4 - sources/SatElite/ForMani/Global/String.C | 121 -- sources/SatElite/ForMani/Global/String.h | 107 -- sources/SatElite/ForMani/Global/depend.mak | 85 -- sources/SatElite/ForMani/depend.mak | 0 sources/SatElite/ForMani/dummy.mak | 0 sources/SatElite/ForMani/options.mak | 11 - sources/SatElite/ForMani/standard.mak | 2 - sources/SatElite/ForMani/template.mak | 125 -- sources/SatElite/SatELite/BcnfWriter.iC | 79 -- sources/SatElite/SatELite/Heap.h | 77 -- sources/SatElite/SatELite/Main.C | 568 -------- sources/SatElite/SatELite/Main.h | 32 - sources/SatElite/SatELite/Main_debug.C | 171 --- sources/SatElite/SatELite/Makefile | 3 - sources/SatElite/SatELite/Profile.C | 3 - sources/SatElite/SatELite/Profile.h | 29 - sources/SatElite/SatELite/Queue.h | 34 - sources/SatElite/SatELite/Solver.C | 997 -------------- sources/SatElite/SatELite/Solver.h | 486 ------- sources/SatElite/SatELite/SolverTypes.h | 52 - sources/SatElite/SatELite/Solver_clause.iC | 386 ------ sources/SatElite/SatELite/Solver_debug.C | 46 - sources/SatElite/SatELite/Solver_subsume.C | 1159 ----------------- sources/SatElite/SatELite/TmpFiles.C | 62 - sources/SatElite/SatELite/TmpFiles.h | 13 - sources/SatElite/SatELite/VarOrder.h | 107 -- {sources/glucose/utils => utils}/Makefile | 0 {sources/glucose/utils => utils}/Options.cc | 10 +- {sources/glucose/utils => utils}/Options.h | 6 +- {sources/glucose/utils => utils}/ParseUtils.h | 6 +- {sources/glucose/utils => utils}/System.cc | 12 +- {sources/glucose/utils => utils}/System.h | 10 +- 78 files changed, 659 insertions(+), 7248 deletions(-) delete mode 100755 build.sh delete mode 100755 clean.sh rename {sources/glucose/core => core}/BoundedQueue.h (96%) rename {sources/glucose/core => core}/Constants.h (100%) rename {sources/glucose/core => core}/Dimacs.h (97%) rename {sources/glucose/core => core}/Main.cc (89%) rename {sources/glucose/core => core}/Makefile (100%) rename {sources/glucose/core => core}/Solver.cc (76%) rename {sources/glucose/core => core}/Solver.h (92%) rename {sources/glucose/core => core}/SolverTypes.h (95%) delete mode 100755 glucose.sh rename {sources/glucose/mtl => mtl}/Alg.h (97%) rename {sources/glucose/mtl => mtl}/Alloc.h (98%) rename {sources/glucose/mtl => mtl}/Heap.h (98%) rename {sources/glucose/mtl => mtl}/IntTypes.h (97%) rename {sources/glucose/mtl => mtl}/Map.h (99%) rename {sources/glucose/mtl => mtl}/Queue.h (97%) rename {sources/glucose/mtl => mtl}/Sort.h (97%) rename {sources/glucose/mtl => mtl}/Vec.h (98%) rename {sources/glucose/mtl => mtl}/XAlloc.h (96%) rename {sources/glucose/mtl => mtl}/config.mk (100%) rename {sources/glucose/mtl => mtl}/template.mk (98%) rename {sources/glucose/simp => simp}/Main.cc (59%) rename {sources/glucose/simp => simp}/Makefile (64%) rename {sources/glucose/simp => simp}/SimpSolver.cc (95%) rename {sources/glucose/simp => simp}/SimpSolver.h (98%) delete mode 100644 sources/SatElite/ForMani/ADTs/FSet.h delete mode 100644 sources/SatElite/ForMani/ADTs/File.C delete mode 100644 sources/SatElite/ForMani/ADTs/File.h delete mode 100644 sources/SatElite/ForMani/ADTs/File.od delete mode 100644 sources/SatElite/ForMani/ADTs/File.or delete mode 100644 sources/SatElite/ForMani/ADTs/Hash_standard.h delete mode 100644 sources/SatElite/ForMani/ADTs/Makefile delete mode 100644 sources/SatElite/ForMani/ADTs/Map.h delete mode 100644 sources/SatElite/ForMani/ADTs/Set.h delete mode 100644 sources/SatElite/ForMani/ADTs/Sort.h delete mode 100644 sources/SatElite/ForMani/ADTs/StackAlloc.h delete mode 100644 sources/SatElite/ForMani/ADTs/VecAlloc.h delete mode 100644 sources/SatElite/ForMani/ADTs/VecMaps.h delete mode 100644 sources/SatElite/ForMani/ADTs/depend.mak delete mode 100644 sources/SatElite/ForMani/Global/Global.C delete mode 100644 sources/SatElite/ForMani/Global/Global.h delete mode 100644 sources/SatElite/ForMani/Global/Global.od delete mode 100644 sources/SatElite/ForMani/Global/Global.or delete mode 100644 sources/SatElite/ForMani/Global/Makefile delete mode 100644 sources/SatElite/ForMani/Global/String.C delete mode 100644 sources/SatElite/ForMani/Global/String.h delete mode 100644 sources/SatElite/ForMani/Global/depend.mak delete mode 100644 sources/SatElite/ForMani/depend.mak delete mode 100644 sources/SatElite/ForMani/dummy.mak delete mode 100644 sources/SatElite/ForMani/options.mak delete mode 100644 sources/SatElite/ForMani/standard.mak delete mode 100644 sources/SatElite/ForMani/template.mak delete mode 100644 sources/SatElite/SatELite/BcnfWriter.iC delete mode 100644 sources/SatElite/SatELite/Heap.h delete mode 100644 sources/SatElite/SatELite/Main.C delete mode 100644 sources/SatElite/SatELite/Main.h delete mode 100644 sources/SatElite/SatELite/Main_debug.C delete mode 100644 sources/SatElite/SatELite/Makefile delete mode 100644 sources/SatElite/SatELite/Profile.C delete mode 100644 sources/SatElite/SatELite/Profile.h delete mode 100644 sources/SatElite/SatELite/Queue.h delete mode 100644 sources/SatElite/SatELite/Solver.C delete mode 100644 sources/SatElite/SatELite/Solver.h delete mode 100644 sources/SatElite/SatELite/SolverTypes.h delete mode 100644 sources/SatElite/SatELite/Solver_clause.iC delete mode 100644 sources/SatElite/SatELite/Solver_debug.C delete mode 100644 sources/SatElite/SatELite/Solver_subsume.C delete mode 100644 sources/SatElite/SatELite/TmpFiles.C delete mode 100644 sources/SatElite/SatELite/TmpFiles.h delete mode 100644 sources/SatElite/SatELite/VarOrder.h rename {sources/glucose/utils => utils}/Makefile (100%) rename {sources/glucose/utils => utils}/Options.cc (92%) rename {sources/glucose/utils => utils}/Options.h (99%) rename {sources/glucose/utils => utils}/ParseUtils.h (98%) rename {sources/glucose/utils => utils}/System.cc (93%) rename {sources/glucose/utils => utils}/System.h (92%) diff --git a/README.md b/README.md index 687f320..77c5e83 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ # Glucose SAT solver -This is the release 2.1 of the glucose SAT solver. +This is the release 3.0 of the glucose SAT solver. It is based on [Minisat 2.2](http://minisat.se/MiniSat.html) -For compiling: ```./build.sh``` +For compiling: + - ```cd simp``` +- ```make``` + + +For running: ```simp/glucose BENCHNAME``` -For running: ```glucose.sh BENCHNAME``` diff --git a/build.sh b/build.sh deleted file mode 100755 index 1e4c9f9..0000000 --- a/build.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -export FM=$PWD/sources/SatElite/ForMani - -cd sources/SatElite/SatELite -make r -cp SatELite_release ../../.. - -cd ../../glucose/core -make rs -cp glucose_static ../../.. - diff --git a/clean.sh b/clean.sh deleted file mode 100755 index abd5701..0000000 --- a/clean.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -export FM=$PWD/sources/SatElite/ForMani -rm -rf glucose_static -rm -rf SatELite_release - -cd sources/SatElite/SatELite -make clean - -cd ../../glucose/core -make clean - diff --git a/sources/glucose/core/BoundedQueue.h b/core/BoundedQueue.h similarity index 96% rename from sources/glucose/core/BoundedQueue.h rename to core/BoundedQueue.h index 9d9b0f4..b17354f 100644 --- a/sources/glucose/core/BoundedQueue.h +++ b/core/BoundedQueue.h @@ -27,7 +27,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA //================================================================================================= -namespace Minisat { +namespace Glucose { template class bqueue { @@ -54,7 +54,7 @@ class bqueue { queuesize++; sumofqueue += x; elems[first] = x; - if ((++first) == maxsize) first = 0; + if ((++first) == maxsize) {first = 0;last = 0;} } T peek() { assert(queuesize>0); return elems[last]; } @@ -74,7 +74,7 @@ class bqueue { void growTo(int size) { elems.growTo(size); - first=0; maxsize=size; queuesize = 0; + first=0; maxsize=size; queuesize = 0;last = 0; for(int i=0;i #include "utils/ParseUtils.h" #include "core/SolverTypes.h" -namespace Minisat { +namespace Glucose { //================================================================================================= // DIMACS Parser: diff --git a/sources/glucose/core/Main.cc b/core/Main.cc similarity index 89% rename from sources/glucose/core/Main.cc rename to core/Main.cc index 6bef40d..3aece05 100644 --- a/sources/glucose/core/Main.cc +++ b/core/Main.cc @@ -38,7 +38,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "core/Dimacs.h" #include "core/Solver.h" -using namespace Minisat; +using namespace Glucose; //================================================================================================= @@ -47,7 +47,7 @@ void printStats(Solver& solver) { double cpu_time = cpuTime(); double mem_used = 0;//memUsedPeak(); - printf("c restarts : %"PRIu64" (%"PRIu64" conflicts in avg)\n", solver.starts,solver.conflicts/solver.starts); + printf("c restarts : %"PRIu64" (%"PRIu64" conflicts in avg)\n", solver.starts,(solver.starts>0 ?solver.conflicts/solver.starts : 0)); printf("c blocked restarts : %"PRIu64" (multiple: %"PRIu64") \n", solver.nbstopsrestarts,solver.nbstopsrestartssame); printf("c last block at restart : %"PRIu64"\n",solver.lastblockatrestart); printf("c nb ReduceDB : %lld\n", solver.nbReduceDB); @@ -89,7 +89,7 @@ static void SIGINT_exit(int signum) { int main(int argc, char** argv) { - printf("c\nc This is glucose 2.1 -- based on MiniSAT (Many thanks to MiniSAT team)\nc\n"); + printf("c\nc This is glucose 3.0 -- based on MiniSAT (Many thanks to MiniSAT team)\nc\n"); try { setUsageHelp("c USAGE: %s [options] \n\n where input may be either in plain or gzipped DIMACS.\n"); // printf("This is MiniSat 2.0 beta\n"); @@ -102,10 +102,12 @@ int main(int argc, char** argv) // Extra options: // IntOption verb ("MAIN", "verb", "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2)); + BoolOption mod ("MAIN", "model", "show model.", false); IntOption vv ("MAIN", "vv", "Verbosity every vv conflicts", 10000, IntRange(1,INT32_MAX)); IntOption cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX)); IntOption mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX)); + parseOptions(argc, argv, true); Solver S; @@ -113,6 +115,7 @@ int main(int argc, char** argv) S.verbosity = verb; S.verbEveryConflicts = vv; + S.showModel = mod; solver = &S; // Use signal handlers that forcibly quit until the solver will be able to respond to // interrupts: @@ -153,8 +156,11 @@ int main(int argc, char** argv) parse_DIMACS(in, S); gzclose(in); - FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL; + + + FILE* res = (argc >= 3) ? fopen(argv[argc-1], "wb") : NULL; + if (S.verbosity > 0){ printf("c | Number of variables: %12d |\n", S.nVars()); printf("c | Number of clauses: %12d |\n", S.nClauses()); } @@ -170,6 +176,7 @@ int main(int argc, char** argv) //signal(SIGXCPU,SIGINT_interrupt); if (!S.simplify()){ + if (S.certifiedOutput != NULL) fprintf(S.certifiedOutput, "0\n"), fclose(S.certifiedOutput); if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res); if (S.verbosity > 0){ printf("c =========================================================================================================\n"); @@ -179,27 +186,31 @@ int main(int argc, char** argv) printf("s UNSATISFIABLE\n"); exit(20); } - + vec dummy; lbool ret = S.solveLimited(dummy); if (S.verbosity > 0){ printStats(S); printf("\n"); } - if (res != NULL){ - if (ret == l_True){ - fprintf(res, "SAT\n"); - for (int 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 - fprintf(res, "INDET\n"); - fclose(res); - } else { - printf(ret == l_True ? "s SATISFIABLE\n" : ret == l_False ? "s UNSATISFIABLE\n" : "s INDETERMINATE\n"); - if(ret==l_True) { + + //-------------- Result is put in a external file + if (res != NULL){ + if (ret == l_True){ + fprintf(res, "SAT\n"); + for (int 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 + fprintf(res, "INDET\n"); + fclose(res); + + //-------------- Want certified output + } else { + printf(ret == l_True ? "s SATISFIABLE\n" : ret == l_False ? "s UNSATISFIABLE\n" : "s INDETERMINATE\n"); + if(S.showModel && ret==l_True) { printf("v "); for (int i = 0; i < S.nVars(); i++) if (S.model[i] != l_Undef) @@ -207,7 +218,8 @@ int main(int argc, char** argv) printf(" 0\n"); } } - + + #ifdef NDEBUG exit(ret == l_True ? 10 : ret == l_False ? 20 : 0); // (faster than "return", which will invoke the destructor for 'Solver') #else diff --git a/sources/glucose/core/Makefile b/core/Makefile similarity index 100% rename from sources/glucose/core/Makefile rename to core/Makefile diff --git a/sources/glucose/core/Solver.cc b/core/Solver.cc similarity index 76% rename from sources/glucose/core/Solver.cc rename to core/Solver.cc index 2fa98e2..e3c474a 100644 --- a/sources/glucose/core/Solver.cc +++ b/core/Solver.cc @@ -1,5 +1,5 @@ /***************************************************************************************[Solver.cc] - Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon + Glucose -- Copyright (c) 2013, Gilles Audemard, Laurent Simon CRIL - Univ. Artois, France LRI - Univ. Paris Sud, France @@ -32,8 +32,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "mtl/Sort.h" #include "core/Solver.h" #include "core/Constants.h" +#include "utils/System.h" -using namespace Minisat; +using namespace Glucose; //================================================================================================= // Options: @@ -42,15 +43,18 @@ static const char* _cat = "CORE"; static const char* _cr = "CORE -- RESTART"; static const char* _cred = "CORE -- REDUCE"; static const char* _cm = "CORE -- MINIMIZE"; +static const char* _certified = "CORE -- CERTIFIED UNSAT"; + +static BoolOption opt_incremental (_cat,"incremental", "Use incremental SAT solving",false); static DoubleOption opt_K (_cr, "K", "The constant used to force restart", 0.8, DoubleRange(0, false, 1, false)); static DoubleOption opt_R (_cr, "R", "The constant used to block restart", 1.4, DoubleRange(1, false, 5, false)); static IntOption opt_size_lbd_queue (_cr, "szLBDQueue", "The size of moving average for LBD (restarts)", 50, IntRange(10, INT32_MAX)); static IntOption opt_size_trail_queue (_cr, "szTrailQueue", "The size of moving average for trail (block restarts)", 5000, IntRange(10, INT32_MAX)); -static IntOption opt_first_reduce_db (_cred, "firstReduceDB", "The number of conflicts before the first reduce DB", 4000, IntRange(0, INT32_MAX)); +static IntOption opt_first_reduce_db (_cred, "firstReduceDB", "The number of conflicts before the first reduce DB", 2000, IntRange(0, INT32_MAX)); static IntOption opt_inc_reduce_db (_cred, "incReduceDB", "Increment for reduce DB", 300, IntRange(0, INT32_MAX)); static IntOption opt_spec_inc_reduce_db (_cred, "specialIncReduceDB", "Special increment for reduce DB", 1000, IntRange(0, INT32_MAX)); static IntOption opt_lb_lbd_frozen_clause (_cred, "minLBDFrozenClause", "Protect clauses if their LBD decrease and is lower than (for one turn)", 30, IntRange(0, INT32_MAX)); @@ -59,7 +63,7 @@ static IntOption opt_lb_size_minimzing_clause (_cm, "minSizeMinimizingCl static IntOption opt_lb_lbd_minimzing_clause (_cm, "minLBDMinimizingClause", "The min LBD required to minimize clause", 6, IntRange(3, INT32_MAX)); -static DoubleOption opt_var_decay (_cat, "var-decay", "The variable activity decay factor", 0.95, DoubleRange(0, false, 1, false)); +static DoubleOption opt_var_decay (_cat, "var-decay", "The variable activity decay factor", 0.8, DoubleRange(0, false, 1, false)); static DoubleOption opt_clause_decay (_cat, "cla-decay", "The clause activity decay factor", 0.999, DoubleRange(0, false, 1, false)); static DoubleOption opt_random_var_freq (_cat, "rnd-freq", "The frequency with which the decision heuristic tries to choose a random variable", 0, DoubleRange(0, true, 1, true)); static DoubleOption opt_random_seed (_cat, "rnd-seed", "Used by the random variable selection", 91648253, DoubleRange(0, false, HUGE_VAL, false)); @@ -73,6 +77,10 @@ static DoubleOption opt_restart_inc (_cat, "rinc", "Restart interv static DoubleOption opt_garbage_frac (_cat, "gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered", 0.20, DoubleRange(0, false, HUGE_VAL, false)); + BoolOption opt_certified (_certified, "certified", "Certified UNSAT using DRUP format", false); + StringOption opt_certified_file (_certified, "certified-output", "Certified UNSAT output file", "NULL"); + + //================================================================================================= // Constructor/Destructor: @@ -82,6 +90,7 @@ Solver::Solver() : // Parameters (user settable): // verbosity (0) + , showModel (0) , K (opt_K) , R (opt_R) , sizeLBDQueue (opt_size_lbd_queue) @@ -101,13 +110,14 @@ Solver::Solver() : , rnd_pol (false) , rnd_init_act (opt_rnd_init_act) , garbage_frac (opt_garbage_frac) - - + , certifiedOutput (NULL) + , certifiedUNSAT (opt_certified) // Statistics: (formerly in 'SolverStats') // , nbRemovedClauses(0),nbReducedClauses(0), nbDL2(0),nbBin(0),nbUn(0) , nbReduceDB(0) - , solves(0), starts(0), decisions(0), rnd_decisions(0), propagations(0), conflicts(0),nbstopsrestarts(0),nbstopsrestartssame(0),lastblockatrestart(0) + , solves(0), starts(0), decisions(0), rnd_decisions(0), propagations(0),conflicts(0),conflictsRestarts(0),nbstopsrestarts(0),nbstopsrestartssame(0),lastblockatrestart(0) , dec_vars(0), clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0) + , curRestart(1) , ok (true) , cla_inc (1) @@ -126,7 +136,28 @@ Solver::Solver() : , conflict_budget (-1) , propagation_budget (-1) , asynch_interrupt (false) -{MYFLAG=0;} + , incremental(opt_incremental) + , nbVarsInitialFormula(INT32_MAX) +{ + MYFLAG=0; + // Initialize only first time. Useful for incremental solving, useless otherwise + lbdQueue.initSize(sizeLBDQueue); + trailQueue.initSize(sizeTrailQueue); + sumLBD = 0; + nbclausesbeforereduce = firstReduceDB; + totalTime4Sat=0;totalTime4Unsat=0; + nbSatCalls=0;nbUnsatCalls=0; + + + if(certifiedUNSAT) { + if(!strcmp(opt_certified_file,"NULL")) { + certifiedOutput = fopen("/dev/stdout", "wb"); + } else { + certifiedOutput = fopen(opt_certified_file, "wb"); + } + // fprintf(certifiedOutput,"o proof DRUP\n"); + } +} Solver::~Solver() @@ -134,6 +165,23 @@ Solver::~Solver() } +/**************************************************************** + Set the incremental mode +****************************************************************/ + +// This function set the incremental mode to true. +// You can add special code for this mode here. + +void Solver::setIncrementalMode() { + incremental = true; +} + +// Number of variables without selectors +void Solver::initNbInitialVars(int nb) { + nbVarsInitialFormula = nb; +} + + //================================================================================================= // Minor methods: @@ -162,6 +210,7 @@ Var Solver::newVar(bool sign, bool dvar) } + bool Solver::addClause_(vec& ps) { assert(decisionLevel() == 0); @@ -169,13 +218,36 @@ bool Solver::addClause_(vec& ps) // Check if clause is satisfied and remove false/duplicate literals: sort(ps); - Lit p; int i, j; + + vec oc; + oc.clear(); + + Lit p; int i, j, flag = 0; + if(certifiedUNSAT) { + for (i = j = 0, p = lit_Undef; i < ps.size(); i++) { + oc.push(ps[i]); + if (value(ps[i]) == l_True || ps[i] == ~p || value(ps[i]) == l_False) + flag = 1; + } + } + for (i = j = 0, p = lit_Undef; i < ps.size(); i++) - if (value(ps[i]) == l_True || ps[i] == ~p) - return true; - else if (value(ps[i]) != l_False && ps[i] != p) - ps[j++] = p = ps[i]; + if (value(ps[i]) == l_True || ps[i] == ~p) + return true; + else if (value(ps[i]) != l_False && ps[i] != p) + ps[j++] = p = ps[i]; ps.shrink(i - j); + + if (flag && (certifiedUNSAT)) { + for (i = j = 0, p = lit_Undef; i < ps.size(); i++) + fprintf(certifiedOutput, "%i ", (var(ps[i]) + 1) * (-2 * sign(ps[i]) + 1)); + fprintf(certifiedOutput, "0\n"); + + fprintf(certifiedOutput, "d "); + for (i = j = 0, p = lit_Undef; i < oc.size(); i++) + fprintf(certifiedOutput, "%i ", (var(oc[i]) + 1) * (-2 * sign(oc[i]) + 1)); + fprintf(certifiedOutput, "0\n"); + } if (ps.size() == 0) return ok = false; @@ -194,6 +266,7 @@ bool Solver::addClause_(vec& ps) void Solver::attachClause(CRef cr) { const Clause& c = ca[cr]; + assert(c.size() > 1); if(c.size()==2) { watchesBin[~c[0]].push(Watcher(cr, c[1])); @@ -236,23 +309,141 @@ void Solver::detachClause(CRef cr, bool strict) { void Solver::removeClause(CRef cr) { - + Clause& c = ca[cr]; + + if (certifiedUNSAT) { + fprintf(certifiedOutput, "d "); + for (int i = 0; i < c.size(); i++) + fprintf(certifiedOutput, "%i ", (var(c[i]) + 1) * (-2 * sign(c[i]) + 1)); + fprintf(certifiedOutput, "0\n"); + } + detachClause(cr); // Don't leave pointers to free'd memory! if (locked(c)) vardata[var(c[0])].reason = CRef_Undef; - c.mark(1); - ca.free(cr); + c.mark(1); + ca.free(cr); } bool Solver::satisfied(const Clause& c) const { + if(incremental) // Check clauses with many selectors is too time consuming + return (value(c[0]) == l_True) || (value(c[1]) == l_True); + + // Default mode. for (int i = 0; i < c.size(); i++) if (value(c[i]) == l_True) return true; - return false; } + return false; +} + +/************************************************************ + * Compute LBD functions + *************************************************************/ + +inline unsigned int Solver::computeLBD(const vec & lits,int end) { + int nblevels = 0; + MYFLAG++; + + if(incremental) { // ----------------- INCREMENTAL MODE + if(end==-1) end = lits.size(); + unsigned int nbDone = 0; + for(int i=0;i=end) break; + if(isSelector(var(lits[i]))) continue; + nbDone++; + int l = level(var(lits[i])); + if (permDiff[l] != MYFLAG) { + permDiff[l] = MYFLAG; + nblevels++; + } + } + } else { // -------- DEFAULT MODE. NOT A LOT OF DIFFERENCES... BUT EASIER TO READ + for(int i=0;i=c.sizeWithoutSelectors()) break; + if(isSelector(var(c[i]))) continue; + nbDone++; + int l = level(var(c[i])); + if (permDiff[l] != MYFLAG) { + permDiff[l] = MYFLAG; + nblevels++; + } + } + } else { // -------- DEFAULT MODE. NOT A LOT OF DIFFERENCES... BUT EASIER TO READ + for(int i=0;i &out_learnt) { + + // Find the LBD measure + unsigned int lbd = computeLBD(out_learnt); + Lit p = ~out_learnt[0]; + + if(lbd<=lbLBDMinimizingClause){ + MYFLAG++; + + for(int i = 1;i& wbin = watchesBin[p]; + int nb = 0; + for(int k = 0;k0) { + nbReducedClauses++; + for(int i = 1;i= trail_lim[level]; c--){ Var x = var(trail[c]); assigns [x] = l_Undef; - if (phase_saving > 1 || (phase_saving == 1) && c > trail_lim.last()) + if (phase_saving > 1 || ((phase_saving == 1) && c > trail_lim.last())) polarity[x] = sign(trail[c]); insertVarOrder(x); } qhead = trail_lim[level]; trail.shrink(trail.size() - trail_lim[level]); trail_lim.shrink(trail_lim.size() - level); - } } + } +} //================================================================================================= @@ -312,7 +504,7 @@ Lit Solver::pickBranchLit() | rest of literals. There may be others from the same level though. | |________________________________________________________________________________________________@*/ -void Solver::analyze(CRef confl, vec& out_learnt, int& out_btlevel,unsigned int &lbd) +void Solver::analyze(CRef confl, vec& out_learnt,vec&selectors, int& out_btlevel,unsigned int &lbd,unsigned int &szWithoutSelectors) { int pathC = 0; Lit p = lit_Undef; @@ -335,26 +527,46 @@ void Solver::analyze(CRef confl, vec& out_learnt, int& out_btlevel,unsigned c[0] = c[1], c[1] = tmp; } - if (c.learnt()) + if (c.learnt()) claBumpActivity(c); +#ifdef DYNAMICNBLEVEL + // DYNAMIC NBLEVEL trick (see competition'09 companion paper) + if(c.learnt() && c.lbd()>2) { + unsigned int nblevels = computeLBD(c); + if(nblevels+1 0){ + if(!isSelector(var(q))) varBumpActivity(var(q)); - seen[var(q)] = 1; - if (level(var(q)) >= decisionLevel()) { - pathC++; + seen[var(q)] = 1; + if (level(var(q)) >= decisionLevel()) { + pathC++; #ifdef UPDATEVARACTIVITY - // UPDATEVARACTIVITY trick (see competition'09 companion paper) - if((reason(var(q))!= CRef_Undef) && ca[reason(var(q))].learnt()) - lastDecisionLevel.push(q); + // UPDATEVARACTIVITY trick (see competition'09 companion paper) + if(!isSelector(var(q)) && (reason(var(q))!= CRef_Undef) && ca[reason(var(q))].learnt()) + lastDecisionLevel.push(q); #endif - - } else { - out_learnt.push(q); - } + + } else { + if(isSelector(var(q))) { + assert(value(q) == l_False); + selectors.push(q); + } else + out_learnt.push(q); + } } } @@ -371,6 +583,10 @@ void Solver::analyze(CRef confl, vec& out_learnt, int& out_btlevel,unsigned // Simplify conflict clause: // int i, j; + + for(int i = 0;i& out_learnt, int& out_btlevel,unsigned out_learnt[j++] = out_learnt[i]; else{ Clause& c = ca[reason(var(out_learnt[i]))]; - for (int k = 1; k < c.size(); k++) + // Thanks to Siert Wieringa for this bug fix! + for (int k = ((c.size()==2) ? 0:1); k < c.size(); k++) if (!seen[var(c[k])] && level(var(c[k])) > 0){ out_learnt[j++] = out_learnt[i]; break; } @@ -409,64 +626,8 @@ void Solver::analyze(CRef confl, vec& out_learnt, int& out_btlevel,unsigned Then, we reduce clauses with small LBD. Otherwise, this can be useless */ - if(out_learnt.size()<=lbSizeMinimizingClause) { - // Find the LBD measure - lbd = 0; - MYFLAG++; - for(int i=0;i& wbin = watchesBin[p]; - int nb = 0; - for(int k = 0;k0) { - nbReducedClauses++; - for(int i = 1;i& out_learnt, int& out_btlevel,unsigned } - // Find the LBD measure - lbd = 0; - MYFLAG++; - for(int i=0;i0) break; + } + } else + szWithoutSelectors = out_learnt.size(); - int l = level(var(out_learnt[i])); - if (permDiff[l] != MYFLAG) { - permDiff[l] = MYFLAG; - lbd++; - } - } - + // Compute LBD + lbd = computeLBD(out_learnt,out_learnt.size()-selectors.size()); #ifdef UPDATEVARACTIVITY @@ -513,7 +674,8 @@ void Solver::analyze(CRef confl, vec& out_learnt, int& out_btlevel,unsigned - for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) + for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) + for(int j = 0 ; j ");printLit(imp);printf("\n"); uncheckedEnqueue(imp,wbin[k].cref); } } @@ -671,11 +832,37 @@ CRef Solver::propagate() *j++ = w; continue; } // Look for new watch: - for (int k = 2; k < c.size(); k++) - if (value(c[k]) != l_False){ - c[1] = c[k]; c[k] = false_lit; - watches[~c[1]].push(w); - goto NextClause; } + if(incremental) { // ----------------- INCREMENTAL MODE + int choosenPos = -1; + for (int k = 2; k < c.size(); k++) { + + if (value(c[k]) != l_False){ + if(decisionLevel()>assumptions.size()) { + choosenPos = k; + break; + } else { + choosenPos = k; + + if(value(c[k])==l_True || !isSelector(var(c[k]))) { + break; + } + } + + } + } + if(choosenPos!=-1) { + c[1] = c[choosenPos]; c[choosenPos] = false_lit; + watches[~c[1]].push(w); + goto NextClause; } + } else { // ----------------- DEFAULT MODE (NOT INCREMENTAL) + for (int k = 2; k < c.size(); k++) { + + if (value(c[k]) != l_False){ + c[1] = c[k]; c[k] = false_lit; + watches[~c[1]].push(w); + goto NextClause; } + } + } // Did not find watch -- clause is unit under assignment: *j++ = w; @@ -688,29 +875,6 @@ CRef Solver::propagate() }else { uncheckedEnqueue(first, cr); -#ifdef DYNAMICNBLEVEL - // DYNAMIC NBLEVEL trick (see competition'09 companion paper) - if(c.learnt() && c.lbd()>2) { - MYFLAG++; - unsigned int nblevels =0; - for(int i=0;i& cs) Clause& c = ca[cs[i]]; - if (c.size()>2 && satisfied(c)) // A bug if we remove size ==2, We need to correct it, but later. + if (satisfied(c)) removeClause(cs[i]); else cs[j++] = cs[i]; @@ -863,21 +1027,22 @@ bool Solver::simplify() | all variables are decision variables, this means that the clause set is satisfiable. 'l_False' | if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. |________________________________________________________________________________________________@*/ -static long conf4stats = 0,cons = 0,curRestart=1; lbool Solver::search(int nof_conflicts) { assert(ok); int backtrack_level; int conflictC = 0; - vec learnt_clause; - unsigned int nblevels; + vec learnt_clause,selectors; + unsigned int nblevels,szWoutSelectors; bool blocked=false; starts++; for (;;){ CRef confl = propagate(); if (confl != CRef_Undef){ // CONFLICT - conflicts++; conflictC++; + conflicts++; conflictC++;conflictsRestarts++; + if(conflicts%5000==0 && var_decay<0.95) + var_decay += 0.01; if (verbosity >= 1 && conflicts%verbEveryConflicts==0){ printf("c | %8d %7d %5d | %7d %8d %8d | %5d %8d %6d %8d | %6.3f %% |\n", @@ -889,39 +1054,46 @@ lbool Solver::search(int nof_conflicts) return l_False; } - + trailQueue.push(trail.size()); - if( conflicts>LOWER_BOUND_FOR_BLOCKING_RESTART && lbdQueue.isvalid() && trail.size()>R*trailQueue.getavg()) { + // BLOCK RESTART (CP 2012 paper) + if( conflictsRestarts>LOWER_BOUND_FOR_BLOCKING_RESTART && lbdQueue.isvalid() && trail.size()>R*trailQueue.getavg()) { lbdQueue.fastclear(); nbstopsrestarts++; if(!blocked) {lastblockatrestart=starts;nbstopsrestartssame++;blocked=true;} } learnt_clause.clear(); - analyze(confl, learnt_clause, backtrack_level,nblevels); + selectors.clear(); + analyze(confl, learnt_clause, selectors,backtrack_level,nblevels,szWoutSelectors); - conf4stats++;cons++; lbdQueue.push(nblevels); sumLBD += nblevels; - cancelUntil(backtrack_level); + cancelUntil(backtrack_level); + + if (certifiedUNSAT) { + for (int i = 0; i < learnt_clause.size(); i++) + fprintf(certifiedOutput, "%i " , (var(learnt_clause[i]) + 1) * + (-2 * sign(learnt_clause[i]) + 1) ); + fprintf(certifiedOutput, "0\n"); + } if (learnt_clause.size() == 1){ uncheckedEnqueue(learnt_clause[0]);nbUn++; }else{ CRef cr = ca.alloc(learnt_clause, true); ca[cr].setLBD(nblevels); + ca[cr].setSizeWithoutSelectors(szWoutSelectors); if(nblevels<=2) nbDL2++; // stats if(ca[cr].size()==2) nbBin++; // stats - learnts.push(cr); attachClause(cr); claBumpActivity(ca[cr]); uncheckedEnqueue(learnt_clause[0], cr); } - varDecayActivity(); claDecayActivity(); @@ -929,20 +1101,23 @@ lbool Solver::search(int nof_conflicts) }else{ // Our dynamic restart, see the SAT09 competition compagnion paper if ( - ( lbdQueue.isvalid() && ((lbdQueue.getavg()*K) > (sumLBD / conf4stats)))) { + ( lbdQueue.isvalid() && ((lbdQueue.getavg()*K) > (sumLBD / conflictsRestarts)))) { lbdQueue.fastclear(); progress_estimate = progressEstimate(); - cancelUntil(0); + int bt = 0; + if(incremental) { // DO NOT BACKTRACK UNTIL 0.. USELESS + bt = (decisionLevel()=0) + if(conflicts>=curRestart* nbclausesbeforereduce) { assert(learnts.size()>0); @@ -1001,32 +1176,55 @@ double Solver::progressEstimate() const return progress / nVars(); } +void Solver::printIncrementalStats() { + + printf("c---------- Glucose Stats -------------------------\n"); + printf("c restarts : %lld\n", starts); + printf("c nb ReduceDB : %lld\n", nbReduceDB); + printf("c nb removed Clauses : %lld\n",nbRemovedClauses); + printf("c nb learnts DL2 : %lld\n", nbDL2); + printf("c nb learnts size 2 : %lld\n", nbBin); + printf("c nb learnts size 1 : %lld\n", nbUn); + + printf("c conflicts : %lld \n",conflicts); + printf("c decisions : %lld\n",decisions); + printf("c propagations : %lld\n",propagations); + + printf("c SAT Calls : %d in %g seconds\n",nbSatCalls,totalTime4Sat); + printf("c UNSAT Calls : %d in %g seconds\n",nbUnsatCalls,totalTime4Unsat); + printf("c--------------------------------------------------\n"); + + +} + // NOTE: assumptions passed in member-variable 'assumptions'. lbool Solver::solve_() { + + if(incremental && certifiedUNSAT) { + printf("Can not use incremental and certified unsat in the same time\n"); + exit(-1); + } model.clear(); conflict.clear(); if (!ok) return l_False; + double curTime = cpuTime(); - lbdQueue.initSize(sizeLBDQueue); - - trailQueue.initSize(sizeTrailQueue); - sumLBD = 0; solves++; - + + lbool status = l_Undef; - nbclausesbeforereduce = firstReduceDB; - if(verbosity>=1) { + if(!incremental && verbosity>=1) { printf("c ========================================[ MAGIC CONSTANTS ]==============================================\n"); printf("c | Constants are supposed to work well together :-) |\n"); printf("c | however, if you find better choices, please let us known... |\n"); printf("c |-------------------------------------------------------------------------------------------------------|\n"); printf("c | | | |\n"); printf("c | - Restarts: | - Reduce Clause DB: | - Minimize Asserting: |\n"); - printf("c | * LBD Queue : %6d | * First : %6d | * size < %3d |\n",lbdQueue.maxSize(),firstReduceDB,lbSizeMinimizingClause); + printf("c | * LBD Queue : %6d | * First : %6d | * size < %3d |\n",lbdQueue.maxSize(),nbclausesbeforereduce,lbSizeMinimizingClause); printf("c | * Trail Queue : %6d | * Inc : %6d | * lbd < %3d |\n",trailQueue.maxSize(),incReduceDB,lbLBDMinimizingClause); printf("c | * K : %6.2f | * Special : %6d | |\n",K,specialIncReduceDB); printf("c | * R : %6.2f | * Protected : (lbd)< %2d | |\n",R,lbLBDFrozenClause); @@ -1048,10 +1246,17 @@ printf("c ==================================[ Search Statistics (every %6d confl curr_restarts++; } - if (verbosity >= 1) + if (!incremental && verbosity >= 1) printf("c =========================================================================================================\n"); + if (certifiedUNSAT){ // Want certified output + if (status == l_False) + fprintf(certifiedOutput, "0\n"); + fclose(certifiedOutput); + } + + if (status == l_True){ // Extend & copy model: model.growTo(nVars()); @@ -1059,7 +1264,21 @@ printf("c ==================================[ Search Statistics (every %6d confl }else if (status == l_False && conflict.size() == 0) ok = false; + + cancelUntil(0); + + double finalTime = cpuTime(); + if(status==l_True) { + nbSatCalls++; + totalTime4Sat +=(finalTime-curTime); + } + if(status==l_False) { + nbUnsatCalls++; + totalTime4Unsat +=(finalTime-curTime); + } + + return status; } diff --git a/sources/glucose/core/Solver.h b/core/Solver.h similarity index 92% rename from sources/glucose/core/Solver.h rename to core/Solver.h index b69b721..d923628 100644 --- a/sources/glucose/core/Solver.h +++ b/core/Solver.h @@ -26,8 +26,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_Solver_h -#define Minisat_Solver_h +#ifndef Glucose_Solver_h +#define Glucose_Solver_h #include "mtl/Vec.h" #include "mtl/Heap.h" @@ -38,7 +38,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "core/Constants.h" -namespace Minisat { +namespace Glucose { //================================================================================================= // Solver -- the main class: @@ -79,6 +79,7 @@ class Solver { void toDimacs (FILE* f, Clause& c, vec& map, Var& max); void printLit(Lit l); void printClause(CRef c); + void printInitialClause(CRef c); // Convenience versions of 'toDimacs()': void toDimacs (const char* file); void toDimacs (const char* file, Lit p); @@ -102,6 +103,11 @@ class Solver { int nVars () const; // The current number of variables. int nFreeVars () const; + // Incremental mode + void setIncrementalMode(); + void initNbInitialVars(int nb); + void printIncrementalStats(); + // Resource contraints: // void setConfBudget(int64_t x); @@ -116,6 +122,9 @@ class Solver { void checkGarbage(double gf); void checkGarbage(); + + + // Extra results: (read-only member variable) // vec model; // If problem is satisfiable, this vector contains the model (if any). @@ -126,6 +135,7 @@ class Solver { // int verbosity; int verbEveryConflicts; + int showModel; // Constants For restarts double K; double R; @@ -152,15 +162,18 @@ class Solver { bool rnd_init_act; // Initialize variable activities with a small random value. double garbage_frac; // The fraction of wasted memory allowed before a garbage collection is triggered. + // Certified UNSAT ( Thanks to Marijn Heule) + FILE* certifiedOutput; + bool certifiedUNSAT; // Statistics: (read-only member variable) // - uint64_t nbRemovedClauses,nbReducedClauses,nbDL2,nbBin,nbUn,nbReduceDB,solves, starts, decisions, rnd_decisions, propagations, conflicts,nbstopsrestarts,nbstopsrestartssame,lastblockatrestart; + uint64_t nbRemovedClauses,nbReducedClauses,nbDL2,nbBin,nbUn,nbReduceDB,solves, starts, decisions, rnd_decisions, propagations, conflicts,conflictsRestarts,nbstopsrestarts,nbstopsrestartssame,lastblockatrestart; uint64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals; protected: - + long curRestart; // Helper structures: // struct VarData { CRef reason; int level; }; @@ -216,7 +229,7 @@ class Solver { Heap 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'. - vec permDiff; // permDiff[var] contains the current conflict number... Used to count the number of LBD + vec permDiff; // permDiff[var] contains the current conflict number... Used to count the number of LBD #ifdef UPDATEVARACTIVITY // UPDATEVARACTIVITY trick (see competition'09 companion paper) @@ -229,6 +242,7 @@ class Solver { bqueue trailQueue,lbdQueue; // Bounded queues for restarts. float sumLBD; // used to compute the global average of LBD. Restarts... + int sumAssumptions; // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is @@ -238,7 +252,7 @@ class Solver { vec analyze_stack; vec analyze_toclear; vec add_tmp; - unsigned long MYFLAG; + unsigned int MYFLAG; double max_learnts; @@ -251,6 +265,15 @@ class Solver { int64_t propagation_budget; // -1 means no budget. bool asynch_interrupt; + + // Variables added for incremental mode + int incremental; // Use incremental SAT Solver + int nbVarsInitialFormula; // nb VAR in formula without assumptions (incremental SAT) + double totalTime4Sat,totalTime4Unsat; + int nbSatCalls,nbUnsatCalls; + vec assumptionPositions,initialPositions; + + // Main internal methods: // void insertVarOrder (Var x); // Insert a variable in the decision order priority queue. @@ -260,7 +283,7 @@ class Solver { bool enqueue (Lit p, CRef from = CRef_Undef); // Test if fact 'p' contradicts current state, enqueue otherwise. CRef propagate (); // Perform unit propagation. Returns possibly conflicting clause. void cancelUntil (int level); // Backtrack until a certain level. - void analyze (CRef confl, vec& out_learnt, int& out_btlevel,unsigned int &nblevels); // (bt = backtrack) + void analyze (CRef confl, vec& out_learnt, vec & selectors, int& out_btlevel,unsigned int &nblevels,unsigned int &szWithoutSelectors); // (bt = backtrack) void analyzeFinal (Lit p, vec& 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); // Search for a given number of conflicts. @@ -285,6 +308,10 @@ class Solver { bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state. bool satisfied (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state. + unsigned int computeLBD(const vec & lits,int end=-1); + unsigned int computeLBD(const Clause &c); + void minimisationWithBinaryResolution(vec &out_learnt); + void relocAll (ClauseAllocator& to); // Misc: @@ -295,6 +322,7 @@ class Solver { int level (Var x) const; double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ... bool withinBudget () const; + inline bool isSelector(Var v) {return (incremental && v>nbVarsInitialFormula);} // Static helpers: // @@ -354,7 +382,14 @@ inline bool Solver::addEmptyClause () { add_tmp.clear( inline bool Solver::addClause (Lit p) { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); } inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); } inline bool Solver::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 bool Solver::locked (const Clause& c) const { return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c; } + inline bool Solver::locked (const Clause& c) const { + if(c.size()>2) + return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c; + return + (value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c) + || + (value(c[1]) == l_True && reason(var(c[1])) != CRef_Undef && ca.lea(reason(var(c[1]))) == &c); + } inline void Solver::newDecisionLevel() { trail_lim.push(trail.size()); } inline int Solver::decisionLevel () const { return trail_lim.size(); } @@ -423,6 +458,18 @@ inline void Solver::printClause(CRef cr) } } +inline void Solver::printInitialClause(CRef cr) +{ + Clause &c = ca[cr]; + for (int i = 0; i < c.size(); i++){ + if(!isSelector(var(c[i]))) { + printLit(c[i]); + printf(" "); + } + } +} + + //================================================================================================= } diff --git a/sources/glucose/core/SolverTypes.h b/core/SolverTypes.h similarity index 95% rename from sources/glucose/core/SolverTypes.h rename to core/SolverTypes.h index 2854f85..b310489 100644 --- a/sources/glucose/core/SolverTypes.h +++ b/core/SolverTypes.h @@ -27,8 +27,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA **************************************************************************************************/ -#ifndef Minisat_SolverTypes_h -#define Minisat_SolverTypes_h +#ifndef Glucose_SolverTypes_h +#define Glucose_SolverTypes_h #include @@ -38,7 +38,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "mtl/Map.h" #include "mtl/Alloc.h" -namespace Minisat { +namespace Glucose { //================================================================================================= // Variables, literals, lifted booleans, clauses: @@ -55,7 +55,7 @@ struct Lit { int x; // Use this as a constructor: - friend Lit mkLit(Var var, bool sign = false); + friend Lit mkLit(Var var, bool sign); bool operator == (Lit p) const { return x == p.x; } bool operator != (Lit p) const { return x != p.x; } @@ -63,7 +63,7 @@ struct Lit { }; -inline Lit mkLit (Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; } +inline Lit mkLit (Var var, bool sign = false) { Lit p; p.x = var + var + (int)sign; return p; } inline Lit operator ~(Lit p) { Lit q; q.x = p.x ^ 1; return q; } inline Lit operator ^(Lit p, bool b) { Lit q; q.x = p.x ^ (unsigned int)b; return q; } inline bool sign (Lit p) { return p.x & 1; } @@ -89,9 +89,9 @@ const Lit lit_Error = { -1 }; // } // does enough constant propagation to produce sensible code, and this appears to be somewhat // fragile unfortunately. -#define l_True (lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants. -#define l_False (lbool((uint8_t)1)) -#define l_Undef (lbool((uint8_t)2)) +#define l_True (Glucose::lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants. +#define l_False (Glucose::lbool((uint8_t)1)) +#define l_Undef (Glucose::lbool((uint8_t)2)) class lbool { uint8_t value; @@ -137,6 +137,8 @@ class Clause { unsigned lbd : 26; unsigned canbedel : 1; unsigned size : 32; + unsigned szWithoutSelectors : 32; + } header; union { Lit lit; float act; uint32_t abs; CRef rel; } data[0]; @@ -200,6 +202,9 @@ class Clause { unsigned int lbd () const { return header.lbd; } void setCanBeDel(bool b) {header.canbedel = b;} bool canBeDel() {return header.canbedel;} + void setSizeWithoutSelectors (unsigned int n) {header.szWithoutSelectors = n; } + unsigned int sizeWithoutSelectors () const { return header.szWithoutSelectors; } + }; @@ -263,6 +268,7 @@ class ClauseAllocator : public RegionAllocator if (to[cr].learnt()) { to[cr].activity() = c.activity(); to[cr].setLBD(c.lbd()); + to[cr].setSizeWithoutSelectors(c.sizeWithoutSelectors()); to[cr].setCanBeDel(c.canBeDel()); } else if (to[cr].has_extra()) to[cr].calcAbstraction(); diff --git a/glucose.sh b/glucose.sh deleted file mode 100755 index 1a85205..0000000 --- a/glucose.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -if [ "x$1" = "x" ]; then - echo "USAGE: glucose.sh " - exit 1 -fi - - -# to set in evaluation environment -mypath=. - -# To set in a normal envirnement -#mypath=. -#TMPDIR=/tmp - -TMP=$TMPDIR/glucose_$$ #set this to the location of temporary files -SE=$mypath/SatELite_release #set this to the executable of SatELite -RS=$mypath/glucose_static #set this to the executable of RSat -INPUT=$1; -shift -echo "c" -echo "c Starting SatElite Preprocessing" -echo "c" -$SE $INPUT $TMP.cnf $TMP.vmap $TMP.elim -X=$? -echo "c" -echo "c Starting glucose" -echo "c" -if [ $X == 0 ]; then - #SatElite terminated correctly - $RS $TMP.cnf -verbosity=0 $TMP.result "$@" - #more $TMP.result - X=$? - if [ $X == 20 ]; then - echo "s UNSATISFIABLE" - rm -f $TMP.cnf $TMP.vmap $TMP.elim $TMP.result - exit 20 - #Don't call SatElite for model extension. - elif [ $X != 10 ]; then - #timeout/unknown, nothing to do, just clean up and exit. - rm -f $TMP.cnf $TMP.vmap $TMP.elim $TMP.result - exit $X - fi - #SATISFIABLE, call SatElite for model extension - $SE +ext $INPUT $TMP.result $TMP.vmap $TMP.elim "$@" - X=$? -elif [ $X == 11 ]; then - #SatElite died, glucose must take care of the rest - $RS $INPUT -verbosity=0 #but we must force glucose to print out result here!!! - X=$? -elif [ $X == 12 ]; then - #SatElite prints out usage message - #There is nothing to do here. - X=0 -fi - -rm -f $TMP.cnf $TMP.vmap $TMP.elim $TMP.result -exit $X diff --git a/sources/glucose/mtl/Alg.h b/mtl/Alg.h similarity index 97% rename from sources/glucose/mtl/Alg.h rename to mtl/Alg.h index bb1ee5a..9afb455 100644 --- a/sources/glucose/mtl/Alg.h +++ b/mtl/Alg.h @@ -18,12 +18,12 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_Alg_h -#define Minisat_Alg_h +#ifndef Glucose_Alg_h +#define Glucose_Alg_h #include "mtl/Vec.h" -namespace Minisat { +namespace Glucose { //================================================================================================= // Useful functions on vector-like types: diff --git a/sources/glucose/mtl/Alloc.h b/mtl/Alloc.h similarity index 98% rename from sources/glucose/mtl/Alloc.h rename to mtl/Alloc.h index f2f492c..61264a2 100644 --- a/sources/glucose/mtl/Alloc.h +++ b/mtl/Alloc.h @@ -18,13 +18,13 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA **************************************************************************************************/ -#ifndef Minisat_Alloc_h -#define Minisat_Alloc_h +#ifndef Glucose_Alloc_h +#define Glucose_Alloc_h #include "mtl/XAlloc.h" #include "mtl/Vec.h" -namespace Minisat { +namespace Glucose { //================================================================================================= // Simple Region-based memory allocator: diff --git a/sources/glucose/mtl/Heap.h b/mtl/Heap.h similarity index 98% rename from sources/glucose/mtl/Heap.h rename to mtl/Heap.h index 226407e..e134b98 100644 --- a/sources/glucose/mtl/Heap.h +++ b/mtl/Heap.h @@ -18,12 +18,12 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_Heap_h -#define Minisat_Heap_h +#ifndef Glucose_Heap_h +#define Glucose_Heap_h #include "mtl/Vec.h" -namespace Minisat { +namespace Glucose { //================================================================================================= // A heap implementation with support for decrease/increase key. diff --git a/sources/glucose/mtl/IntTypes.h b/mtl/IntTypes.h similarity index 97% rename from sources/glucose/mtl/IntTypes.h rename to mtl/IntTypes.h index 7041d58..2d8d4e8 100644 --- a/sources/glucose/mtl/IntTypes.h +++ b/mtl/IntTypes.h @@ -17,8 +17,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_IntTypes_h -#define Minisat_IntTypes_h +#ifndef Glucose_IntTypes_h +#define Glucose_IntTypes_h #ifdef __sun // Not sure if there are newer versions that support C99 headers. The diff --git a/sources/glucose/mtl/Map.h b/mtl/Map.h similarity index 99% rename from sources/glucose/mtl/Map.h rename to mtl/Map.h index 8a82d0e..f29ae2d 100644 --- a/sources/glucose/mtl/Map.h +++ b/mtl/Map.h @@ -17,13 +17,13 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_Map_h -#define Minisat_Map_h +#ifndef Glucose_Map_h +#define Glucose_Map_h #include "mtl/IntTypes.h" #include "mtl/Vec.h" -namespace Minisat { +namespace Glucose { //================================================================================================= // Default hash/equals functions diff --git a/sources/glucose/mtl/Queue.h b/mtl/Queue.h similarity index 97% rename from sources/glucose/mtl/Queue.h rename to mtl/Queue.h index 17567d6..6bb1d56 100644 --- a/sources/glucose/mtl/Queue.h +++ b/mtl/Queue.h @@ -18,12 +18,12 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_Queue_h -#define Minisat_Queue_h +#ifndef Glucose_Queue_h +#define Glucose_Queue_h #include "mtl/Vec.h" -namespace Minisat { +namespace Glucose { //================================================================================================= diff --git a/sources/glucose/mtl/Sort.h b/mtl/Sort.h similarity index 97% rename from sources/glucose/mtl/Sort.h rename to mtl/Sort.h index e9313ef..50cb448 100644 --- a/sources/glucose/mtl/Sort.h +++ b/mtl/Sort.h @@ -18,8 +18,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_Sort_h -#define Minisat_Sort_h +#ifndef Glucose_Sort_h +#define Glucose_Sort_h #include "mtl/Vec.h" @@ -27,7 +27,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA // Some sorting algorithms for vec's -namespace Minisat { +namespace Glucose { template struct LessThan_default { diff --git a/sources/glucose/mtl/Vec.h b/mtl/Vec.h similarity index 98% rename from sources/glucose/mtl/Vec.h rename to mtl/Vec.h index 9e22085..e93a2ca 100644 --- a/sources/glucose/mtl/Vec.h +++ b/mtl/Vec.h @@ -18,8 +18,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_Vec_h -#define Minisat_Vec_h +#ifndef Glucose_Vec_h +#define Glucose_Vec_h #include #include @@ -27,7 +27,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "mtl/IntTypes.h" #include "mtl/XAlloc.h" -namespace Minisat { +namespace Glucose { //================================================================================================= // Automatically resizable arrays diff --git a/sources/glucose/mtl/XAlloc.h b/mtl/XAlloc.h similarity index 96% rename from sources/glucose/mtl/XAlloc.h rename to mtl/XAlloc.h index f3d8176..f8ca4fe 100644 --- a/sources/glucose/mtl/XAlloc.h +++ b/mtl/XAlloc.h @@ -18,14 +18,14 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA **************************************************************************************************/ -#ifndef Minisat_XAlloc_h -#define Minisat_XAlloc_h +#ifndef Glucose_XAlloc_h +#define Glucose_XAlloc_h #include #include #include -namespace Minisat { +namespace Glucose { //================================================================================================= // Simple layer on top of malloc/realloc to catch out-of-memory situtaions and provide some typing: diff --git a/sources/glucose/mtl/config.mk b/mtl/config.mk similarity index 100% rename from sources/glucose/mtl/config.mk rename to mtl/config.mk diff --git a/sources/glucose/mtl/template.mk b/mtl/template.mk similarity index 98% rename from sources/glucose/mtl/template.mk rename to mtl/template.mk index 3f443fc..f9bea84 100644 --- a/sources/glucose/mtl/template.mk +++ b/mtl/template.mk @@ -17,7 +17,7 @@ PCOBJS = $(addsuffix p, $(COBJS)) DCOBJS = $(addsuffix d, $(COBJS)) RCOBJS = $(addsuffix r, $(COBJS)) - +#CXX ?= /usr/gcc-/bin/g++-4.7.0 CXX ?= g++ CFLAGS ?= -Wall -Wno-parentheses LFLAGS ?= -Wall diff --git a/sources/glucose/simp/Main.cc b/simp/Main.cc similarity index 59% rename from sources/glucose/simp/Main.cc rename to simp/Main.cc index e59d73b..8aa30b6 100644 --- a/sources/glucose/simp/Main.cc +++ b/simp/Main.cc @@ -1,6 +1,15 @@ /*****************************************************************************************[Main.cc] + Glucose -- Copyright (c) 2009, Gilles Audemard, Laurent Simon + CRIL - Univ. Artois, France + LRI - Univ. Paris Sud, France + +Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions and copyrights of +Glucose are exactly the same as Minisat on which it is based on. (see below). + +--------------- + Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -Copyright (c) 2007, 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, @@ -30,7 +39,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "core/Dimacs.h" #include "simp/SimpSolver.h" -using namespace Minisat; +using namespace Glucose; //================================================================================================= @@ -38,17 +47,28 @@ using namespace Minisat; void printStats(Solver& solver) { double cpu_time = cpuTime(); - double mem_used = memUsedPeak(); - printf("restarts : %"PRIu64"\n", solver.starts); - printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", solver.conflicts , solver.conflicts /cpu_time); - printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions /cpu_time); - printf("propagations : %-12"PRIu64" (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time); - printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals); + double mem_used = 0;//memUsedPeak(); + printf("c restarts : %"PRIu64" (%"PRIu64" conflicts in avg)\n", solver.starts,(solver.starts>0 ?solver.conflicts/solver.starts : 0)); + printf("c blocked restarts : %"PRIu64" (multiple: %"PRIu64") \n", solver.nbstopsrestarts,solver.nbstopsrestartssame); + printf("c last block at restart : %"PRIu64"\n",solver.lastblockatrestart); + printf("c nb ReduceDB : %lld\n", solver.nbReduceDB); + printf("c nb removed Clauses : %lld\n",solver.nbRemovedClauses); + printf("c nb learnts DL2 : %lld\n", solver.nbDL2); + printf("c nb learnts size 2 : %lld\n", solver.nbBin); + printf("c nb learnts size 1 : %lld\n", solver.nbUn); + + printf("c conflicts : %-12"PRIu64" (%.0f /sec)\n", solver.conflicts , solver.conflicts /cpu_time); + printf("c decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions /cpu_time); + printf("c propagations : %-12"PRIu64" (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time); + printf("c conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals); + printf("c nb reduced Clauses : %lld\n",solver.nbReducedClauses); + if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used); - printf("CPU time : %g s\n", cpu_time); + printf("c CPU time : %g s\n", cpu_time); } + static Solver* solver; // Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case // for this feature of the Solver as it may take longer than an immediate call to '_exit()'. @@ -71,8 +91,10 @@ static void SIGINT_exit(int signum) { int main(int argc, char** argv) { try { - setUsageHelp("USAGE: %s [options] \n\n where input may be either in plain or gzipped DIMACS.\n"); - // printf("This is MiniSat 2.0 beta\n"); + printf("c\nc This is glucose 3.0 -- based on MiniSAT (Many thanks to MiniSAT team)\nc Simplification mode is turned on\nc\n"); + + setUsageHelp("c USAGE: %s [options] \n\n where input may be either in plain or gzipped DIMACS.\n"); + #if defined(__linux__) fpu_control_t oldcw, newcw; @@ -82,6 +104,8 @@ int main(int argc, char** argv) // Extra options: // IntOption verb ("MAIN", "verb", "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2)); + BoolOption mod ("MAIN", "model", "show model.", false); + IntOption vv ("MAIN", "vv", "Verbosity every vv conflicts", 10000, IntRange(1,INT32_MAX)); BoolOption pre ("MAIN", "pre", "Completely turn on/off any preprocessing.", true); StringOption dimacs ("MAIN", "dimacs", "If given, stop after preprocessing and write the result to this file."); IntOption cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX)); @@ -92,10 +116,12 @@ int main(int argc, char** argv) SimpSolver S; double initial_time = cpuTime(); + S.parsing = 1; if (!pre) S.eliminate(true); S.verbosity = verb; - + S.verbEveryConflicts = vv; + S.showModel = mod; solver = &S; // Use signal handlers that forcibly quit until the solver will be able to respond to // interrupts: @@ -130,47 +156,50 @@ int main(int argc, char** argv) if (in == NULL) printf("ERROR! Could not open file: %s\n", argc == 1 ? "" : argv[1]), exit(1); - if (S.verbosity > 0){ - printf("============================[ Problem Statistics ]=============================\n"); - printf("| |\n"); } + if (S.verbosity > 0){ + printf("c ========================================[ Problem Statistics ]===========================================\n"); + printf("c | |\n"); } + FILE* res = (argc >= 3) ? fopen(argv[argc-1], "wb") : NULL; parse_DIMACS(in, S); gzclose(in); - FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL; - if (S.verbosity > 0){ - printf("| Number of variables: %12d |\n", S.nVars()); - printf("| Number of clauses: %12d |\n", S.nClauses()); } + if (S.verbosity > 0){ + printf("c | Number of variables: %12d |\n", S.nVars()); + printf("c | Number of clauses: %12d |\n", S.nClauses()); } double parsed_time = cpuTime(); - if (S.verbosity > 0) - printf("| Parse time: %12.2f s |\n", parsed_time - initial_time); + if (S.verbosity > 0){ + printf("c | Parse time: %12.2f s |\n", parsed_time - initial_time); + printf("c | |\n"); } // Change to signal-handlers that will only notify the solver and allow it to terminate // voluntarily: signal(SIGINT, SIGINT_interrupt); signal(SIGXCPU,SIGINT_interrupt); + S.parsing = 0; S.eliminate(true); double simplified_time = cpuTime(); if (S.verbosity > 0){ - printf("| Simplification time: %12.2f s |\n", simplified_time - parsed_time); - printf("| |\n"); } + printf("c | Simplification time: %12.2f s |\n", simplified_time - parsed_time); + printf("c | |\n"); } if (!S.okay()){ + if (S.certifiedUNSAT) fprintf(S.certifiedOutput, "0\n"), fclose(S.certifiedOutput); if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res); if (S.verbosity > 0){ - printf("===============================================================================\n"); - printf("Solved by simplification\n"); + printf("c =========================================================================================================\n"); + printf("Solved by simplification\n"); printStats(S); printf("\n"); } - printf("UNSATISFIABLE\n"); + printf("s UNSATISFIABLE\n"); exit(20); } if (dimacs){ if (S.verbosity > 0) - printf("==============================[ Writing DIMACS ]===============================\n"); + printf("c =======================================[ Writing DIMACS ]===============================================\n"); S.toDimacs((const char*)dimacs); if (S.verbosity > 0) printStats(S); @@ -183,20 +212,31 @@ int main(int argc, char** argv) if (S.verbosity > 0){ printStats(S); printf("\n"); } - printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n"); + printf(ret == l_True ? "s SATISFIABLE\n" : ret == l_False ? "s UNSATISFIABLE\n" : "s INDETERMINATE\n"); + if (res != NULL){ if (ret == l_True){ - fprintf(res, "SAT\n"); + printf("SAT\n"); for (int 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 - fprintf(res, "INDET\n"); + } else { + if (ret == l_False){ + fprintf(res, "UNSAT\n"), fclose(res); + } + } fclose(res); - } + } else { + if(S.showModel && ret==l_True) { + printf("v "); + for (int i = 0; i < S.nVars(); i++) + if (S.model[i] != l_Undef) + printf("%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1); + printf(" 0\n"); + } + + } #ifdef NDEBUG exit(ret == l_True ? 10 : ret == l_False ? 20 : 0); // (faster than "return", which will invoke the destructor for 'Solver') @@ -204,7 +244,7 @@ int main(int argc, char** argv) return (ret == l_True ? 10 : ret == l_False ? 20 : 0); #endif } catch (OutOfMemoryException&){ - printf("===============================================================================\n"); + printf("c =========================================================================================================\n"); printf("INDETERMINATE\n"); exit(0); } diff --git a/sources/glucose/simp/Makefile b/simp/Makefile similarity index 64% rename from sources/glucose/simp/Makefile rename to simp/Makefile index 27b45f4..f5d4481 100644 --- a/sources/glucose/simp/Makefile +++ b/simp/Makefile @@ -1,4 +1,5 @@ -EXEC = minisat +EXEC = glucose DEPDIR = mtl utils core +MROOT = $(PWD)/.. include $(MROOT)/mtl/template.mk diff --git a/sources/glucose/simp/SimpSolver.cc b/simp/SimpSolver.cc similarity index 95% rename from sources/glucose/simp/SimpSolver.cc rename to simp/SimpSolver.cc index a1dc16d..50c1362 100644 --- a/sources/glucose/simp/SimpSolver.cc +++ b/simp/SimpSolver.cc @@ -22,7 +22,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "simp/SimpSolver.h" #include "utils/System.h" -using namespace Minisat; +using namespace Glucose; //================================================================================================= // Options: @@ -138,7 +138,6 @@ bool SimpSolver::addClause_(vec& ps) for (int i = 0; i < ps.size(); i++) assert(!isEliminated(var(ps[i]))); #endif - int nclauses = clauses.size(); if (use_rcheck && implied(ps)) @@ -147,6 +146,12 @@ bool SimpSolver::addClause_(vec& ps) if (!Solver::addClause_(ps)) return false; + if(!parsing && certifiedUNSAT) { + for (int i = 0; i < ps.size(); i++) + fprintf(certifiedOutput, "%i " , (var(ps[i]) + 1) * (-2 * sign(ps[i]) + 1) ); + fprintf(certifiedOutput, "0\n"); + } + if (use_simplification && clauses.size() == nclauses + 1){ CRef cr = clauses.last(); const Clause& c = ca[cr]; @@ -197,10 +202,23 @@ bool SimpSolver::strengthenClause(CRef cr, Lit l) // if (!find(subsumption_queue, &c)) subsumption_queue.insert(cr); + if (certifiedUNSAT) { + for (int i = 0; i < c.size(); i++) + if (c[i] != l) fprintf(certifiedOutput, "%i " , (var(c[i]) + 1) * (-2 * sign(c[i]) + 1) ); + fprintf(certifiedOutput, "0\n"); + } + if (c.size() == 2){ removeClause(cr); c.strengthen(l); }else{ + if (certifiedUNSAT) { + fprintf(certifiedOutput, "d "); + for (int i = 0; i < c.size(); i++) + fprintf(certifiedOutput, "%i " , (var(c[i]) + 1) * (-2 * sign(c[i]) + 1) ); + fprintf(certifiedOutput, "0\n"); + } + detachClause(cr, true); c.strengthen(l); attachClause(cr); @@ -507,8 +525,6 @@ bool SimpSolver::eliminateVar(Var v) mkElimClause(elimclauses, ~mkLit(v)); } - for (int i = 0; i < cls.size(); i++) - removeClause(cls[i]); // Produce clauses in cross product: vec& resolvent = add_tmp; @@ -517,9 +533,12 @@ bool SimpSolver::eliminateVar(Var v) if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent)) return false; + for (int i = 0; i < cls.size(); i++) + removeClause(cls[i]); + // Free occurs list for this variable: occurs[v].clear(true); - + // Free watchers lists for this variable, if possible: if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true); if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true); @@ -550,11 +569,13 @@ bool SimpSolver::substitute(Var v, Lit x) subst_clause.push(var(p) == v ? x ^ sign(p) : p); } - removeClause(cls[i]); - + if (!addClause_(subst_clause)) return ok = false; - } + + removeClause(cls[i]); + + } return true; } @@ -586,7 +607,14 @@ bool SimpSolver::eliminate(bool turn_off_elim) // Main simplification loop: // - while (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0){ + + int toPerform = clauses.size()<=4800000; + + if(!toPerform) { + printf("c Too many clauses... No preprocessing\n"); + } + + while (toPerform && (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0)){ gatherTouchedClauses(); // printf(" ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns); @@ -655,7 +683,7 @@ bool SimpSolver::eliminate(bool turn_off_elim) } if (verbosity >= 1 && elimclauses.size() > 0) - printf("| Eliminated clauses: %10.2f Mb |\n", + printf("c | Eliminated clauses: %10.2f Mb |\n", double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024)); return ok; diff --git a/sources/glucose/simp/SimpSolver.h b/simp/SimpSolver.h similarity index 98% rename from sources/glucose/simp/SimpSolver.h rename to simp/SimpSolver.h index 4909018..ff692c3 100644 --- a/sources/glucose/simp/SimpSolver.h +++ b/simp/SimpSolver.h @@ -18,14 +18,14 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_SimpSolver_h -#define Minisat_SimpSolver_h +#ifndef Glucose_SimpSolver_h +#define Glucose_SimpSolver_h #include "mtl/Queue.h" #include "core/Solver.h" -namespace Minisat { +namespace Glucose { //================================================================================================= @@ -80,6 +80,7 @@ class SimpSolver : public Solver { // 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. diff --git a/sources/SatElite/ForMani/ADTs/FSet.h b/sources/SatElite/ForMani/ADTs/FSet.h deleted file mode 100644 index 6625968..0000000 --- a/sources/SatElite/ForMani/ADTs/FSet.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef FSet_h -#define FSet_h - -//================================================================================================= - - -#include "ISet.h" - -// This is an internal type to allow 'ISet' to store sets of formulas. -// -template -class FSet { - struct FromISet { }; - - ISet s; - FSet(ISet src, FromISet) : s(src) { } - -public: - FSet(void) : s() { } - FSet(T singleton) : s((unsigned)singleton) { } - FSet(const T* array, int size) : s((const unsigned*)array, size) { } - FSet(const vec& elems) : s((const vec&)elems) { } - - FSet(const FSet& src) : s(src.s) { } - ~FSet(void) { } - FSet& operator = (FSet& src) { s = src.s; return *this; } - const FSet& operator = (const FSet& src) { s = src.s; return *this; } - - bool empty (void) const { return s.empty(); } - int size (void) const { return s.size(); } - T operator[] (int index) const { return (T)s[index]; } - bool has (T value) const { return s.has((unsigned)value); } - FSet operator + (T value) const { return FSet(s + (unsigned)value, FromISet()); } - FSet& operator += (T value) { s += (unsigned)value; return *this; } - FSet operator + (FSet& other) const { return FSet(s + other.s, FromISet()); } - FSet& operator += (FSet& other) { s += other.s; return *this; } - - unsigned hash (void) const { return s.hash(); } - bool operator == (const FSet& other) const { return s == other.s; } - - unsigned detach (void) { return s.detach(); } - - // Debug: - void dump(void) { s.dump(); } -}; - - -//================================================================================================= - -#endif diff --git a/sources/SatElite/ForMani/ADTs/File.C b/sources/SatElite/ForMani/ADTs/File.C deleted file mode 100644 index 593d4c8..0000000 --- a/sources/SatElite/ForMani/ADTs/File.C +++ /dev/null @@ -1,154 +0,0 @@ -#include "File.h" - - -void File::open(int file_descr, FileMode m, bool own) -{ - if (fd != -1) ::close(fd); - fd = file_descr; - mode = m; - own_fd = own; - pos = 0; - buf = xmalloc(File_BufSize); - if (mode == READ) size = read(fd, buf, File_BufSize); - else size = -1; -} - -void File::open(cchar* name, cchar* mode_) -{ - if (fd != -1) ::close(fd); - bool has_r = strchr(mode_, 'r') != NULL; - bool has_w = strchr(mode_, 'w') != NULL; - bool has_a = strchr(mode_, 'a') != NULL; - bool has_p = strchr(mode_, '+') != NULL; - assert(!(has_r && has_w)); - assert(has_r || has_w || has_a); - - int mask = 0; - if (has_p) mask |= O_RDWR; - else if (has_r) mask |= O_RDONLY; - else mask |= O_WRONLY; - - if (!has_r) mask |= O_CREAT; - if (has_w) mask |= O_TRUNC; - - fd = open64(name, mask, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - - if (fd != -1){ - mode = has_r ? READ : WRITE; - own_fd = true; - pos = 0; - if (has_a) lseek64(fd, 0, SEEK_END); - buf = xmalloc(File_BufSize); - if (mode == READ) size = read(fd, buf, File_BufSize); - else size = -1; - } -} - - -void File::close(void) -{ - if (fd == -1) return; - if (mode == WRITE) - flush(); - xfree(buf); buf = NULL; - if (own_fd) - ::close(fd); - fd = -1; -} - -void File::seek(int64 file_pos, int whence) -{ - if (mode == WRITE){ - flush(); - pos = 0; - lseek64(fd, file_pos, whence); - }else{ - if (whence == SEEK_CUR) lseek64(fd, file_pos - (size - pos), SEEK_CUR); - else lseek64(fd, file_pos, whence); - size = read(fd, buf, File_BufSize); - pos = 0; - } -} - -int64 File::tell(void) -{ - if (mode == WRITE) - return lseek64(fd, 0, SEEK_CUR); - else - return lseek64(fd, 0, SEEK_CUR) - (size - pos); -} - - -//================================================================================================= -// Marshaling: - - -void putUInt(File& out, uint64 val) -{ - if (val < 0x20000000){ - uint v = (uint)val; - if (v < 0x80) - out.putChar(v); - else{ - if (v < 0x2000) - out.putChar(0x80 | (v >> 8)), - out.putChar((uchar)v); - else if (v < 0x200000) - out.putChar(0xA0 | (v >> 16)), - out.putChar((uchar)(v >> 8)), - out.putChar((uchar)v); - else - out.putChar((v >> 24) | 0xC0), - out.putChar((uchar)(v >> 16)), - out.putChar((uchar)(v >> 8)), - out.putChar((uchar)v); - } - }else - out.putChar(0xE0), - out.putChar((uchar)(val >> 56)), - out.putChar((uchar)(val >> 48)), - out.putChar((uchar)(val >> 40)), - out.putChar((uchar)(val >> 32)), - out.putChar((uchar)(val >> 24)), - out.putChar((uchar)(val >> 16)), - out.putChar((uchar)(val >> 8)), - out.putChar((uchar)val); -} - - -uint64 getUInt(File& in) // Returns 0 at end-of-file. -{ - uint byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7; - byte0 = in.getChar(); - if (byte0 == (uint)EOF) return 0; - if (!(byte0 & 0x80)) - return byte0; - else{ - switch ((byte0 & 0x60) >> 5){ - case 0: - byte1 = in.getChar(); - return ((byte0 & 0x1F) << 8) | byte1; - case 1: - byte1 = in.getChar(); - byte2 = in.getChar(); - return ((byte0 & 0x1F) << 16) | (byte1 << 8) | byte2; - case 2: - byte1 = in.getChar(); - byte2 = in.getChar(); - byte3 = in.getChar(); - return ((byte0 & 0x1F) << 24) | (byte1 << 16) | (byte2 << 8) | byte3; - case 3: - byte0 = in.getChar(); - byte1 = in.getChar(); - byte2 = in.getChar(); - byte3 = in.getChar(); - byte4 = in.getChar(); - byte5 = in.getChar(); - byte6 = in.getChar(); - byte7 = in.getChar(); - return ((uint64)((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3) << 32) - | (uint64)((byte4 << 24) | (byte5 << 16) | (byte6 << 8) | byte7); - } - assert(false); - } -} diff --git a/sources/SatElite/ForMani/ADTs/File.h b/sources/SatElite/ForMani/ADTs/File.h deleted file mode 100644 index 6e415df..0000000 --- a/sources/SatElite/ForMani/ADTs/File.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef File_h -#define File_h - -#include -#include -#include - -#ifndef _LARGEFILE64_SOURCE -#define lseek64 ::lseek -#define open64 ::open -#endif - - -//================================================================================================= -// A buffered file abstraction with only 'putChar()' and 'getChar()'. - - -#define File_BufSize 1024 // A small buffer seem to work just as fine as a big one (at least under Linux) - -enum FileMode { READ, WRITE }; - - -// WARNING! This code is not thoroughly tested. May contain bugs! - -class File { - int fd; // Underlying file descriptor. - FileMode mode; // Reading or writing. - uchar* buf; // Read or write buffer. - int size; // Size of buffer (at end of file, less than 'File_BufSize'). - int pos; // Current position in buffer - bool own_fd; // Do we own the file descriptor? If so, will close file in destructor. - -public: - #define DEFAULTS fd(-1), mode(READ), buf(NULL), size(-1), pos(0), own_fd(true) - File(void) : DEFAULTS {} - - File(int fd, FileMode mode, bool own_fd = true) : DEFAULTS { - open(fd, mode, own_fd); } - - File(cchar* name, cchar* mode) : DEFAULTS { - open(name, mode); } - #undef DEFAULTS - - ~File(void) { - close(); } - - void open(int fd, FileMode mode, bool own_fd = true); // Low-level open. If 'own_fd' is FALSE, descriptor will not be closed by destructor. - void open(cchar* name, cchar* mode); // FILE* compatible interface. - void close(void); - - bool null(void) { // TRUE if no file is opened. - return fd == -1; } - - int releaseDescriptor(void) { // Don't run UNIX function 'close()' on descriptor in 'File's 'close()'. - if (mode == READ) - lseek64(fd, pos - size, SEEK_CUR); - own_fd = false; - return fd; } - - FileMode getMode(void) { - return mode; } - - void setMode(FileMode m) { - if (m == mode) return; - if (m == READ){ - flush(); - size = read(fd, buf, File_BufSize); - }else{ - lseek64(fd, pos - size, SEEK_CUR); - size = -1; } - mode = m; - pos = 0; } - - int getCharQ(void) { // Quick version with minimal overhead -- don't call this in the wrong mode! - #ifdef PARANOID - assert(mode == READ); - #endif - if (pos < size) return (uchar)buf[pos++]; - if (size < File_BufSize) return EOF; - size = read(fd, buf, File_BufSize); - pos = 0; - if (size == 0) return EOF; - return (uchar)buf[pos++]; } - - int putCharQ(int chr) { // Quick version with minimal overhead -- don't call this in the wrong mode! - #ifdef PARANOID - assert(mode == WRITE); - #endif - if (pos == File_BufSize) - write(fd, buf, File_BufSize), - pos = 0; - return buf[pos++] = (uchar)chr; } - - int getChar(void) { - if (mode == WRITE) setMode(READ); - return getCharQ(); } - - int putChar(int chr) { - if (mode == READ) setMode(WRITE); - return putCharQ(chr); } - - bool eof(void) { - assert(mode == READ); - if (pos < size) return false; - if (size < File_BufSize) return true; - size = read(fd, buf, File_BufSize); - pos = 0; - if (size == 0) return true; - return false; } - - void flush(void) { - assert(mode == WRITE); - write(fd, buf, pos); - pos = 0; } - - void seek(int64 pos, int whence = SEEK_SET); - int64 tell(void); -}; - - -//================================================================================================= -// Some nice helper functions: - - -void putUInt (File& out, uint64 val); -uint64 getUInt (File& in); -macro uint64 encode64(int64 val) { return (val >= 0) ? (uint64)val << 1 : (((uint64)(~val) << 1) | 1); } -macro int64 decode64(uint64 val) { return ((val & 1) == 0) ? (int64)(val >> 1) : ~(int64)(val >> 1); } -macro void putInt (File& out, int64 val) { putUInt(out, encode64(val)); } -macro uint64 getInt (File& in) { return decode64(getUInt(in)); } - - -//================================================================================================= -#endif diff --git a/sources/SatElite/ForMani/ADTs/File.od b/sources/SatElite/ForMani/ADTs/File.od deleted file mode 100644 index 6169239471fb9b9fd91004a4297b938281742d93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29828 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 struct Hash { uint operator () (const K& key) const { return key.hash(); } }; -template struct Equal { bool operator () (const K& key1, const K& key2) const { return key1 == key2; } }; - -template struct Hash_params { - static uint hash (K key) { return Hash ()(key); } - static bool equal(K key1, K key2) { return Equal()(key1, key2); } -}; - - -//================================================================================================= - - -// DEFINE PATTERN MACRO: -// -// 'code' should use 'key' (hash) or 'key1'/'key2' (equal) to access the elements. The last statement should be a return. -// -#define DefineHash( type, code) template <> struct Hash { uint operator () (type key) const { code } }; -#define DefineEqual(type, code) template <> struct Equal { bool operator () (type key1, type key2) const { code } }; - - -// PAIRS: - -template struct Hash > { uint operator () (const Pair& key) const { return Hash()(key.fst) ^ Hash()(key.snd); } }; -template struct Equal > { bool operator () (const Pair& key1, const Pair& key2) const { return Equal()(key1.fst, key2.fst) && Equal()(key1.snd, key2.snd); } }; - - -// POINTERS: - -#ifdef LP64 -template struct Hash { uint operator () (const K* key) const { uintp tmp = reinterpret_cast(key); return (unsigned)((tmp >> 32) ^ tmp); } }; -template struct Hash { uint operator () (K* key) const { uintp tmp = reinterpret_cast(key); return (unsigned)((tmp >> 32) ^ tmp); } }; -#else -template struct Hash { uint operator () (const K* key) const { return reinterpret_cast(key); } }; -template struct Hash { uint operator () (K* key) const { return reinterpret_cast(key); } }; -#endif - -// C-STRINGS: - -DefineHash (const char*, uint v = 0; for (int i = 0; key[i] != '\0'; i++) v = (v << 3) + key[i]; return v;) -DefineEqual(const char*, if (key1 == key2) return true; else return strcmp(key1, key2) == 0;) -DefineHash (char*, uint v = 0; for (int i = 0; key[i] != '\0'; i++) v = (v << 3) + key[i]; return v;) -DefineEqual(char*, if (key1 == key2) return true; else return strcmp(key1, key2) == 0;) - - -// INTEGER TYPES: - -DefineHash(char , return (uint)key;) -DefineHash(schar , return (uint)key;) -DefineHash(uchar , return (uint)key;) -DefineHash(short , return (uint)key;) -DefineHash(ushort, return (uint)key;) -DefineHash(int , return (uint)key;) -DefineHash(uint , return (uint)key;) -#ifdef LP64 -DefineHash(long , return (uint)(((ulong)key >> 32) ^ key);) -DefineHash(ulong , return (uint)(((ulong)key >> 32) ^ key);) -#else -DefineHash(long , return (uint)key;) -DefineHash(ulong , return (uint)key;) -#endif -DefineHash(int64 , return (uint)(((uint64)key >> 32) ^ key);) -DefineHash(uint64, return (uint)(((uint64)key >> 32) ^ key);) - - -//================================================================================================= - -#endif diff --git a/sources/SatElite/ForMani/ADTs/Makefile b/sources/SatElite/ForMani/ADTs/Makefile deleted file mode 100644 index 3d50a11..0000000 --- a/sources/SatElite/ForMani/ADTs/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -include $(FM)/options.mak -all : $(OBJS) -include $(FM)/template.mak - diff --git a/sources/SatElite/ForMani/ADTs/Map.h b/sources/SatElite/ForMani/ADTs/Map.h deleted file mode 100644 index 7f3e3f0..0000000 --- a/sources/SatElite/ForMani/ADTs/Map.h +++ /dev/null @@ -1,252 +0,0 @@ -/* -Requires copy constructor and assignment operator to be defined for the key and -datum types, (plus default constructor unless null value is passed to constructor) -*/ - - -#ifndef Map_h -#define Map_h - -#include "VecAlloc.h" -#include "Hash_standard.h" - - -//================================================================================================= -// Map implementation: - - -template > -class Map -{ - - struct Cell { - K key; - D datum; - Cell* next; - }; - - VecAlloc alloc; - Cell** table; - int capacity; - int nelems; - const D D_null; - - //--------------------------------------------------------------------------------------------- - - int index(const K& key) const { - return Par::hash(key) % capacity; } // (this is done in 'rehash()' as well) - - int getCapacity(int min_capacity) { - int i; - for (i = 0; prime_twins[i] < min_capacity; i++); - return prime_twins[i]; } - - void init(int min_capacity) { - capacity = getCapacity(min_capacity); - nelems = 0; - table = xmalloc(capacity); - for (int i = 0; i < capacity; i++) table[i] = NULL; } - - void dispose(void) { - for (int i = 0; i < capacity; i++){ - for (Cell* p = table[i]; p != NULL;){ - Cell* next = p->next; - p->key .~K(); - p->datum.~D(); - alloc.free(p); - p = next; } } - xfree(table); - } - - void rehash(int min_capacity) { - int new_capacity = getCapacity(min_capacity); - Cell** new_table = xmalloc(new_capacity); - for (int i = 0; i < new_capacity; i++) new_table[i] = NULL; - - for (int i = 0; i < capacity; i++){ - for (Cell* p = table[i]; p != NULL;){ - Cell* next = p->next; - unsigned j = Par::hash(p->key) % new_capacity; - p->next = new_table[j]; - new_table[j] = p; - p = next; - } - } - xfree(table); - table = new_table; - capacity = new_capacity; - } - - D& newEntry(int i, const K& key, const D& value) { - if (nelems > capacity / 2){ - rehash(capacity * 2); - i = index(key); } - Cell* p = alloc.alloc(); - new (&p->key) K(key); - new (&p->datum) D(value); - p->next = table[i]; - table[i] = p; - nelems++; - return p->datum; } - - //--------------------------------------------------------------------------------------------- - -public: - // Types: - typedef K Key; - typedef D Datum; - - // Constructors: - Map(void) : D_null() { init(1); } - Map(const D& null) : D_null(null) { init(1); } - Map(const D& null, int capacity) : D_null(null) { init(capacity); } - ~Map(void) { dispose(); } - - // Size operations: - int size (void) const { return nelems; } - void clear (void) { dispose(); init(1); } - - // Don't allow copying: - Map& operator = (Map& other) { TEMPLATE_FAIL; } - Map (Map& other) { TEMPLATE_FAIL; } - - //--------------------------------------------------------------------------------------------- - // Export: - - - void domain(vec& result) const { - for (int i = 0; i < capacity; i++) - for (Cell* p = table[i]; p != NULL; p = p->next) - result.push(p->key); } - void range (vec& result) const { - for (int i = 0; i < capacity; i++) - for (Cell* p = table[i]; p != NULL; p = p->next) - result.push(p->datum); } - void pairs (vec >& result) const { - for (int i = 0; i < capacity; i++) - for (Cell* p = table[i]; p != NULL; p = p->next) - result.push(Pair_new(p->key, p->datum)); } - - - //--------------------------------------------------------------------------------------------- - // Main: - - - // Searches for 'key' in the hash table. Returns the value of 'found' or 'notfound'. - // 'found' may use 'Cell* p' refering to the cell that was found; 'notfound' may use - // 'unsigned i', the index position in the table. - #define SEARCH(found, notfound) \ - unsigned i = index(key); \ - for (Cell* p = table[i]; p != NULL; p = p->next){ \ - if (Par::equal(p->key, key)) \ - return found; \ - } \ - return notfound; - - - // Returns a reference to existing or newly created element. - D& ref(const K& key) { - SEARCH( p->datum - , newEntry(i, key, D_null) - );} - - // Sets 'key' to 'value' and returns 'value'. - const D& set(const K& key, const D& value) { - SEARCH( p->datum = value - , newEntry(i, key, value) - );} - - // Sets 'key' to 'value' IF not already set. Returns the value at 'key' after operation (new or old). - const D& weakSet(const K& key, const D& value) { - SEARCH( p->datum - , newEntry(i, key, value) - );} - - // Same as 'set()' but 'key' must not be set already. - const D& add(const K& key, const D& value) { - SEARCH( (PANIC("Tried to add an already existing element to the hashtable."), D_null) - , newEntry(i, key, value) - );} - - // Same as 'has' but returns through reference a pointer to the element (if it exists). - bool peek(const K& key, D*& result) const { - SEARCH( (result = &p->datum, true) - , false - );} - - // Same as 'has' but returns through reference the element (if it exists). - bool peek(const K& key, D& result) const { - SEARCH( (result = p->datum, true) - , false - );} - - // Returns datum at 'key' (or the null value if none) - const D& at(const K& key) { - SEARCH( p->datum - , D_null - );} - - // Same as 'at' but 'key' must contain a value. - const D& find(const K& key) { - SEARCH( p->datum - , (PANIC("Tried to find non-existing element in hashtable."), D_null) - );} - - // Have 'key' been set? - bool has(const K& key) { - SEARCH( true - , false - );} - - // Get the current equal (but not same) key used for 'key'. - const K& findKey(const K& key) { - SEARCH( p->key - , (PANIC("Tried to find non-existing element in hashtable."), *(K*)NULL) - );} - - // Exclude 'key' if exists. - bool exclude(const K& key) { - unsigned i = index(key); - for (Cell** pp = &table[i]; *pp != NULL; pp = &(*pp)->next){ - if (Par::equal((*pp)->key, key)){ - Cell* p = *pp; - *pp = (*pp)->next; - nelems--; - p->key .~K(); - p->datum.~D(); - alloc.free(p); - return true; } - } - return false; - } - - // Same as 'exclude' but 'key' must exist. - void remove(const K& key) { - if (!exclude(key)) PANIC("Tried to remove non-existing element from hashtable."); } - - - #undef SEARCH - - //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String show(void) const { - String header = showf("capacity = %d\n", capacity) - + showf("nelems = %d\n", nelems) - + sref ("D_null = ") + ::show(D_null) + sref("\n\n"); - String body; - int width = strlen(sFree(strnum(capacity))); - for (int i = 0; i < capacity; i++){ - body = body + showf("%*d:", width, i); - for (Cell* p = table[i]; p != NULL; p = p->next) - body = body + sref(" (") + ::show(p->key) + sref(", ") + ::show(p->datum) + sref(")"); - body = body + sref("\n"); - } - return header + body; - } - -}; - - -//================================================================================================= - -#endif diff --git a/sources/SatElite/ForMani/ADTs/Set.h b/sources/SatElite/ForMani/ADTs/Set.h deleted file mode 100644 index e8b7f8b..0000000 --- a/sources/SatElite/ForMani/ADTs/Set.h +++ /dev/null @@ -1,236 +0,0 @@ -/* -Requires copy constructor and assignment operator to be defined for the type, -(plus default constructor unless null value is passed to constructor) -*/ - - -#ifndef Set_h -#define Set_h - -#include "VecAlloc.h" -#include "Hash_standard.h" - -//================================================================================================= -// Set implementation: - - -template > class SetIter; -template > -class Set -{ - struct Cell { - K key; - Cell* next; - }; - - VecAlloc alloc; - Cell** table; - int capacity; - int nelems; - -#ifdef SET_ITERATORS - friend class SetIter; - vec*> iters; - inline void adjustIterators(Cell* p); -public: - int nIterators(void) { return iters.size(); } -private: -#endif - - //--------------------------------------------------------------------------------------------- - - int index(const K& key) const { - return Par::hash(key) % capacity; } // (this is done in 'rehash()' as well) - - int getCapacity(int min_capacity) { - #ifdef SET_DEBUG - return 2; - #endif - int i; - for (i = 0; prime_twins[i] < min_capacity; i++); - return prime_twins[i]; } - - void init(int min_capacity) { - capacity = getCapacity(min_capacity); - nelems = 0; - table = xmalloc(capacity); - for (int i = 0; i < capacity; i++) table[i] = NULL; } - - void dispose(void) { - for (int i = 0; i < capacity; i++){ - for (Cell* p = table[i]; p != NULL;){ - Cell* next = p->next; - p->key .~K(); - alloc.free(p); - p = next; } } - xfree(table); - } - - void rehash(int min_capacity) { - int new_capacity = getCapacity(min_capacity); - Cell** new_table = xmalloc(new_capacity); - for (int i = 0; i < new_capacity; i++) new_table[i] = NULL; - - for (int i = 0; i < capacity; i++){ - for (Cell* p = table[i]; p != NULL;){ - Cell* next = p->next; - unsigned j = Par::hash(p->key) % new_capacity; - p->next = new_table[j]; - new_table[j] = p; - p = next; - } - } - xfree(table); - table = new_table; - capacity = new_capacity; - } - - void newEntry(int i, const K& key) { - #ifndef SET_DEBUG - if (nelems > capacity / 2){ - rehash(capacity * 2); - i = index(key); } - #endif - Cell* p = alloc.alloc(); - new (&p->key) K(key); - p->next = table[i]; - table[i] = p; - nelems++; } - - //--------------------------------------------------------------------------------------------- - -public: - // Types: - typedef K Key; - - // Constructors: - Set(void) { init(1); } - Set(int capacity) { init(capacity); } - ~Set(void) { dispose(); } - - // Size operations: - int size (void) const { return nelems; } - void clear (void) { dispose(); init(1); } - - // Don't allow copying: - Set& operator = (Set& other) { TEMPLATE_FAIL; } - Set (Set& other) { TEMPLATE_FAIL; } - - //--------------------------------------------------------------------------------------------- - // Export: - - // Appends all elements to 'result'. - void toVec(vec& result) const { - for (int i = 0; i < capacity; i++) - for (Cell* p = table[i]; p != NULL; p = p->next) - result.push(p->key); } - - //--------------------------------------------------------------------------------------------- - // Main: - - - // Returns TRUE if element already exists. - bool add(const K& key) { - unsigned i = index(key); - for (Cell* p = table[i]; p != NULL; p = p->next) - if (Par::equal(p->key, key)) - return true; - newEntry(i, key); - return false; } - - - // Returns TRUE if element exists. - bool has(const K& key) { - unsigned i = index(key); - for (Cell* p = table[i]; p != NULL; p = p->next) - if (Par::equal(p->key, key)) - return true; - return false; } - - - // Returns TRUE if element existed and was excluded. - bool exclude(const K& key) { - unsigned i = index(key); - for (Cell** pp = &table[i]; *pp != NULL; pp = &(*pp)->next){ - if (Par::equal((*pp)->key, key)){ - Cell* p = *pp; - #ifdef SET_ITERATORS - adjustIterators(p); - #endif - *pp = (*pp)->next; - nelems--; - p->key .~K(); - alloc.free(p); - return true; } - } - return false; - } - - //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String show(void) const { - String header = showf("capacity = %d\n" , capacity) - + showf("nelems = %d\n\n", nelems); - String body; - int width = strlen(sFree(strnum(capacity))); - for (int i = 0; i < capacity; i++){ - body = body + showf("%*d:", width, i); - for (Cell* p = table[i]; p != NULL; p = p->next) - body = body + sref(" ") + ::show(p->key); - body = body + sref("\n"); - } - return header + body; - } -}; - - -#ifdef SET_ITERATORS -template -class SetIter { - friend class Set; - - Set& S; - int index; - typename Set::Cell* cell; - bool invalid_; - - void advanceIndex(void) { - for(;;){ - index++; - if (index >= S.capacity){ - cell = NULL; - break; - }else if (S.table[index] != NULL){ - cell = S.table[index]; - break; } } } - - void advance(void) { - if (cell != NULL){ - cell = cell->next; - if (cell == NULL) - advanceIndex(); } } - -public: - SetIter(Set& set) : S(set), index(-1), cell(NULL), invalid_(false) { S.iters.push(this); advanceIndex(); } - ~SetIter(void) { for (int i = 0; i < S.iters.size(); i++) if (S.iters[i] == this){ S.iters[i] = S.iters.last(); S.iters.pop(); break; } } - void operator ++ (void) { if (invalid_) invalid_ = false; else advance(); } - void operator ++ (int) { if (invalid_) invalid_ = false; else advance(); } - Key& operator * (void) { assert(!invalid_); return cell->key; } - Key* operator -> (void) { assert(!invalid_); return &cell->key; } - bool done (void) { return cell == NULL; } - bool invalid (void) { return invalid_; } -}; - - -template -void Set::adjustIterators(Cell* p) { - for (int i = 0; i < iters.size(); i++) - if (iters[i]->cell == p) - iters[i]->invalid_ = true, - iters[i]->advance(); } -#endif - - -//================================================================================================= - -#endif diff --git a/sources/SatElite/ForMani/ADTs/Sort.h b/sources/SatElite/ForMani/ADTs/Sort.h deleted file mode 100644 index 2c3f7d1..0000000 --- a/sources/SatElite/ForMani/ADTs/Sort.h +++ /dev/null @@ -1,124 +0,0 @@ -/************************************************************************************************** - -Sort.h -- (C) Niklas Een, 2003 - -Template based sorting routines: sort, sortUnique (remove duplicates). Can be applied either on -'vec's or on standard C arrays (pointers). - -**************************************************************************************************/ - - -#ifndef Sort_h -#define Sort_h - -//#include - - -//================================================================================================= - - -template -struct LessThan_default { - bool operator () (T x, T y) { return x < y; } -}; - - -//================================================================================================= - - -template -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 static inline void selectionSort(T* array, int size) { - selectionSort(array, size, LessThan_default()); } - - -template -void sort(T* array, int size, LessThan lt, double& seed) -{ - if (size <= 15) - selectionSort(array, size, lt); - - else{ - T pivot = array[irand(seed, size)]; - 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, seed); - sort(&array[i], size-i, lt, seed); - } -} -template static inline void sort(T* array, int size, LessThan lt) { - double seed = 91648253; sort(array, size, lt, seed); } -template static inline void sort(T* array, int size) { - sort(array, size, LessThan_default()); } - - -template -void sortUnique(T* array, int& size, LessThan lt) -{ - int i, j; - T last; - - if (size == 0) return; - - sort(array, size, lt); - - i = 1; - last = array[0]; - for (j = 1; j < size; j++){ - if (lt(last, array[j])){ - last = array[i] = array[j]; - i++; } - } - - size = i; -} -template static inline void sortUnique(T* array, int& size) { - sortUnique(array, size, LessThan_default()); } - - -//================================================================================================= -// For 'vec's: - - -template void sort(vec& v, LessThan lt) { - sort((T*)v, v.size(), lt); } -template void sort(vec& v) { - sort(v, LessThan_default()); } - - -template void sortUnique(vec& v, LessThan lt) { - int size = v.size(); - T* data = v.release(); - sortUnique(data, size, lt); - v.~vec(); - new (&v) vec(data, size); } -template void sortUnique(vec& v) { - sortUnique(v, LessThan_default()); } - - -//================================================================================================= -#endif diff --git a/sources/SatElite/ForMani/ADTs/StackAlloc.h b/sources/SatElite/ForMani/ADTs/StackAlloc.h deleted file mode 100644 index c3098bf..0000000 --- a/sources/SatElite/ForMani/ADTs/StackAlloc.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef StackAlloc_h -#define StackAlloc_h - -//================================================================================================= - - -template -struct Allocator { - virtual T* alloc(int nwords) = 0; -}; - - -// STACK ALLOCATOR -// -// 'cap' is capacity, 'lim' is malloc limit (use 'malloc()' for larger sizer -// than this -- unless enough space left on the current stack). -// -template -class StackAlloc : public Allocator { - T* data; - StackAlloc* prev; - int index; - - T* alloc_helper(int n); - StackAlloc(T* d, StackAlloc* p, int i) : data(d), prev(p), index(i) { } - -public: - StackAlloc(void) { data = xmalloc(cap); index = 0; prev = NULL; } - - T* alloc(int n) { - if (index + n <= cap) { T* tmp = data+index; index += n; return tmp; } - else return alloc_helper(n); } - - void freeAll(void); -}; - - -template -T* StackAlloc::alloc_helper(int n) -{ - if (n > lim) { - StackAlloc* singleton = new StackAlloc(xmalloc(n), prev, -1); - prev = singleton; - return singleton->data; } - else{ - StackAlloc* copy = new StackAlloc(data, prev, index); - data = xmalloc(cap); index = n; prev = copy; - assert(n <= cap); - return data; } -} - - -// Call this before allocator is destructed if you do not want to keep the data. -// -template -void StackAlloc::freeAll(void) -{ - StackAlloc* tmp,* ptr; - for (ptr = this; ptr != NULL; ptr = ptr->prev) - xfree(ptr->data); - for (ptr = prev; ptr != NULL;) - tmp = ptr->prev, delete ptr, ptr = tmp; -} - - -//================================================================================================= -#endif diff --git a/sources/SatElite/ForMani/ADTs/VecAlloc.h b/sources/SatElite/ForMani/ADTs/VecAlloc.h deleted file mode 100644 index 008d843..0000000 --- a/sources/SatElite/ForMani/ADTs/VecAlloc.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef VecAlloc_h -#define VecAlloc_h - -#include - -//================================================================================================= - -template -class VecAlloc { - - union Slot { - char data[sizeof(T)]; // (would have liked type 'T' here) - Slot* next; - }; - - Slot* table; - int index; - Slot* recycle; - #ifdef DEBUG - int nallocs; - #endif - - void newTable(void) { - Slot* t = xmalloc(chunk_size); - t[0].next = table; - table = t; - index = 1; } - -public: - VecAlloc(void) { - recycle = NULL; - table = NULL; - #ifdef DEBUG - nallocs = 0; - #endif - newTable(); } - - ~VecAlloc(void) { - #ifdef PARANOID - //#ifdef DEBUG - //if (nallocs != 0) fprintf(stderr, "WARNING! VecAlloc detected leak of %d unit(s) of type '%s'.\n", nallocs, typeid(T).name()); - if (nallocs != 0) fprintf(stderr, "WARNING! VecAlloc detected leak of %d unit(s) of size %d.\n", nallocs, sizeof(T)); - #endif - Slot* curr,* next; - curr = table; - while (curr != NULL) - next = curr[0].next, - xfree(curr), - curr = next; } - - T* alloc(void) { - #ifdef DEBUG - nallocs++; - #endif - if (recycle == NULL){ - if (index >= chunk_size) - newTable(); - return (T*)&table[index++]; - }else{ - T* tmp = (T*)recycle; - recycle = (*recycle).next; - return tmp; - } } - - void free(T* ptr) { - #ifdef DEBUG - nallocs--; - #endif - ((Slot*)ptr)->next = recycle; - recycle = (Slot*)ptr; } -}; - -//================================================================================================= - -#endif diff --git a/sources/SatElite/ForMani/ADTs/VecMaps.h b/sources/SatElite/ForMani/ADTs/VecMaps.h deleted file mode 100644 index 5fbbc08..0000000 --- a/sources/SatElite/ForMani/ADTs/VecMaps.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef VecMaps_h -#define VecMaps_h - -//================================================================================================= - -// TODO: Adapt constructors of 'BitMap' and 'DeckMap' to those of VecMap. - - -class BitMap { - vec v; - bool bool_null; - - unsigned word(int index) const { return (unsigned)index / (sizeof(int)*8); } - unsigned mask(int index) const { return 1 << ((unsigned)index % (sizeof(int)*8)); } -public: - typedef int Key; - typedef bool Datum; - - BitMap(void) : bool_null() { } - BitMap(bool null) : bool_null(null) { } - BitMap(bool null, int capacity) : v((capacity+(sizeof(int)*8)-1) / (sizeof(int)*8), -(int)null), bool_null(null) { } - - bool at(int index) const { - if (word(index) >= (unsigned)v.size()) return bool_null; - else return v[word(index)] & mask(index); } - - void set(int index, bool value) { - if (word(index) >= (unsigned)v.size()) assert(index >= 0), v.growTo(word(index)+1, -(int)bool_null); - if (value == false) - v[word(index)] &= ~mask(index); - else - v[word(index)] |= mask(index); } - - void clear(void) { v.clear(); } -}; - - -template -class VecMap { - vec v; - T T_null; - -public: - typedef int Key; - typedef T Datum; - - VecMap(void) : T_null() { } - VecMap(T null) : T_null(null) { } - VecMap(T null, int capacity) : v(capacity, null), T_null(null) { } - - T at(int index) const { - if ((unsigned)index >= (unsigned)v.size()) return T_null; - else return v[index]; } - - void set(int index, T value) { - if ((unsigned)index >= (unsigned)v.size()) assert(index >= 0), v.growTo(index+1, T_null); - v[index] = value; } - - void clear(void) { v.clear(); } -}; - -template <> -struct VecMap : BitMap { - VecMap(void) { } - VecMap(bool null) : BitMap(null) { } - VecMap(bool null, int capacity) : BitMap(null, capacity) { } -}; - - -template -class DeckMap { - VecMap pos, neg; - -public: - typedef int Key; - typedef T Datum; - - DeckMap(void) { } - DeckMap(T null) : pos(null) , neg(null) { } - DeckMap(T null, int capacity) : pos(null, capacity), neg(null, capacity) { } - - T at(int index) const { - if (index >= 0) return pos.at(index); else return neg.at(~index); } - - void set(int index, Datum value) { - if (index >= 0) pos.set(index, value); else neg.set(~index, value); } - - void clear(void) { pos.clear(); neg.clear(); } -}; - -//================================================================================================= - -#endif diff --git a/sources/SatElite/ForMani/ADTs/depend.mak b/sources/SatElite/ForMani/ADTs/depend.mak deleted file mode 100644 index 891b296..0000000 --- a/sources/SatElite/ForMani/ADTs/depend.mak +++ /dev/null @@ -1,65 +0,0 @@ -File.o: File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - File.h -Global.o: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.o: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h -File.op: File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - File.h -Global.op: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.op: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h -File.od: File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - File.h -Global.od: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.od: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h -File.or: File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - File.h -Global.or: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.or: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h -File.ox: File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - File.h -Global.ox: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.ox: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h diff --git a/sources/SatElite/ForMani/Global/Global.C b/sources/SatElite/ForMani/Global/Global.C deleted file mode 100644 index 145a03d..0000000 --- a/sources/SatElite/ForMani/Global/Global.C +++ /dev/null @@ -1,291 +0,0 @@ -#include -#include -#include -#include -#include - -//#include - - -#if 0 //(__GNUC__ > 2) || (__GNUC__ >= 2 && __GNUC_MINOR__ > 95) -char* nsprintf(const char* format, ...) -{ - char* buf; - va_list args; - va_start(args, format); - vasprintf(&buf, format, args); - va_end(args); - return buf; -} -#else -char* nsprintf(const char* format, ...) -{ - char buf[1024]; - unsigned chars_written; - va_list args; - - va_start(args, format); - chars_written = vsprintf(buf, format, args); - assert(chars_written < sizeof(buf)); - - va_end(args); - return strdup(buf); -} -#endif - - -char* strnum(int num) -{ - #define MAX 11 - char buf[11]; - int i; - bool sign; - char* ret; - - if (num == 0){ - ret = xmalloc(2); - ret[0] = '0'; - ret[1] = '\0'; - return ret; - }else{ - if (num < 0) - num = -num, - sign = true; - else - sign = false; - i = MAX-1; - - while(num != 0) - buf[i] = '0' + (num % 10), - num /= 10, - i--; - - if (sign) - buf[i] = '-', - i--; - - ret = xmalloc(MAX-i); - memcpy(ret, &buf[i+1], MAX-i-1); - ret[MAX-i-1] = '\0'; - return ret; - } -} - - -// Call with '&text' repeatedly to iterate over all tokens. Will change the value of ('char*') 'text' as well as modify the string. -char* strtokr(char** src, const char* seps) -{ - if (*src == NULL) - return NULL; - else{ - while (**src != 0 && strchr(seps, **src) != NULL) (*src)++; - if (**src == 0){ *src = NULL; return NULL; } - char* ret = *src; - do (*src)++; while (**src != 0 && strchr(seps, **src) == NULL); - if (**src == 0) *src = NULL; - else **src = 0, (*src)++; - return ret; - } -} - - -// Returns -1 if file does not exist. -int fileSize(const char* filename) -{ - FILE* in; - int size; - - in = fopen(filename, "rb"); - if (in == NULL) - return -1; - - fseek(in, 0, SEEK_END); - size = (int)ftell(in); - fclose(in); - - return size; -} - - -char* readFile(const char* filename, int* size_) -{ - int size = fileSize(filename); - if (size_ != NULL) - *size_ = size; - - if (size == -1) - return NULL; - else{ - FILE* in = fopen(filename, "rb"); assert(in != NULL); - char* ret = xmalloc(size+1); - fread(ret, 1, size, in); - fclose(in); - ret[size] = '\0'; - return ret; - } -} - - -#define BLOCK_SIZE 65536 -/* -// If you need the code for istreams: -// -char* readFile(ifstream& in, int* size_) -{ - char* data = xmalloc(BLOCK_SIZE); - int cap = BLOCK_SIZE; - int size = 0; - - while (in.good()){ - if (size == cap){ - cap *= 2; - data = xrealloc(data, cap); } - in.read(&data[size], BLOCK_SIZE); - size += in.gcount(); - } - data = xrealloc(data, size+1); - data[size] = '\0'; - - if (size_ != NULL) - *size_ = size; - - return data; -} -*/ - -char* readFile(FILE* in, int* size_) -{ - char* data = xmalloc(BLOCK_SIZE); - int cap = BLOCK_SIZE; - int size = 0; - - while (!feof(in)){ - if (size == cap){ - cap *= 2; - data = xrealloc(data, cap); } - size += fread(&data[size], 1, BLOCK_SIZE, in); - } - data = xrealloc(data, size+1); - data[size] = '\0'; - - if (size_ != NULL) - *size_ = size; - - return data; -} - - -// Read the file named by 'source'. Special name '-' means standard input. A name starting with '^' -// means rest of string is the "file". Several sources can be supplied by separating them with '#' -// In all cases, the returned string should be freed by caller. -// -// If 'output_error' is TRUE, program is halted with an error message if file is missing, -// otherwise 'size' is set to -1 and the name of the (first) missing file is returned. -// -char* extendedReadFile(cchar* sources, int* size, bool output_error) -{ - char* buf = xstrdup(sources); - char* src,* tmp,* orig_buf = buf;; - int tmp_size; - vec result; - - for (;;){ - src = strtokr(&buf, "#"); - if (src == NULL) break; - - if (src[0] == '-' && src[1] == '\0') - tmp = readFile(stdin, &tmp_size); - else if (src[0] == '^'){ - tmp_size = strlen(src+1); - tmp = xstrdup(src+1); } - else{ - tmp = readFile(src, &tmp_size); - if (tmp_size == -1){ - if (output_error) - fprintf(stderr, "ERROR! Could not open file '%s'.\n", src), - exit(1); - else{ - char* ret = xstrdup(src); - assert(size != NULL); - *size = -1; - xfree(buf); - return ret; - } - } - } - - int j = result.size(); - result.growTo(j + tmp_size); - for (int i = 0; i < tmp_size; i++, j++) - result[j] = tmp[i]; - xfree(tmp); - } - xfree(orig_buf); - - result.push('\0'); - if (size != NULL) *size = result.size(); - return result.release(); -} -#undef BLOCK_SIZE - - -void writeFile(const char* filename, const char* data, int size) -{ - if (size == -1) - size = strlen(data); - - FILE* out = fopen(filename, "wb"); assert(out != NULL); - fwrite(data, 1, size, out); - fclose(out); -} - - -/* - size total program size - resident resident set size - share shared pages - trs text (code) - drs data/stack - lrs library - dt dirty pages -*/ -int memReadStat(int field) -{ - char name[256]; - pid_t pid = getpid(); - sprintf(name, "/proc/%d/statm", pid); - FILE* in = fopen(name, "rb"); - if (in == NULL) PANIC("Linux like '/proc' file system not supported."); - int value; - for (; field >= 0; field--) - fscanf(in, "%d", &value); - fclose(in); - return value; -} - - -int64 memUsed (void) { return (int64)memReadStat(0) * (int64)getpagesize(); } -int64 memResident(void) { return (int64)memReadStat(1) * (int64)getpagesize(); } - - -int64 memPhysical(void) -{ - FILE* in = fopen("/proc/meminfo", "rb"); - if (in == NULL) PANIC("Linux like '/proc' file system not supported."); - char buf[1024]; - for(;;){ - fgets(buf, sizeof(buf), in); - if (feof(in)) PANIC("Unexpected format of '/proc/meminfo'."); - if (strncmp(buf, "MemTotal:", 9) == 0){ - fclose(in); - return (int64)atol(buf+9) * 1024; - } - } -} - - -//================================================================================================= -// Sub implementation files: - - -#include "String.C" diff --git a/sources/SatElite/ForMani/Global/Global.h b/sources/SatElite/ForMani/Global/Global.h deleted file mode 100644 index 7b11c59..0000000 --- a/sources/SatElite/ForMani/Global/Global.h +++ /dev/null @@ -1,481 +0,0 @@ -#ifndef Global_h -#define Global_h - -#include -#include -#include -#include -#include -#include -#include -#include -using namespace std; -// NOTE: Machine dependent lines have been tagged "<=MD" - - -//================================================================================================= -// Macros: - - -// Misc: - -#define elemsof(x) (sizeof(x) / sizeof(*(x))) - -#define macro static inline - -#ifndef PANIC // (makefile may define PANIC to eg. 'throw message') -#define PANIC(message) ( fflush(stdout), \ - fprintf(stderr, "PANIC! %s\n", message), fflush(stderr), \ - assert(false) ) -#endif -#define Ping (fflush(stdout), fprintf(stderr, "%s %d\n", __FILE__, __LINE__), fflush(stderr)) - - -// Debug: - -#define pr(format, args...) (fflush(stdout), fprintf(stderr, format, ## args), fflush(stderr)) -#define ss(obj) stempf(show(obj)) - - -// Some GNUC extensions: - -#ifdef __GNUC__ -#define ___noreturn __attribute__ ((__noreturn__)) -#define ___unused __attribute__ ((__unused__)) -#define ___const __attribute__ ((__const__)) -#define ___format(type,fmt,arg) __attribute__ ((__format__(type, fmt, arg) )) -#if (__GNUC__ > 2) || (__GNUC__ >= 2 && __GNUC_MINOR__ > 95) -#define ___malloc __attribute__ ((__malloc__)) -#else -#define ___malloc -#endif -#else -#define ___noreturn -#define ___unused -#define ___const -#define ___format(type,fmt,arg) -#define ___malloc -#endif - -#define INITIALIZER(tag) struct Initializer_ ## tag { Initializer_ ## tag(); } static Initializer_ ## tag ## _instance; Initializer_ ## tag:: Initializer_ ## tag(void) -#define FINALIZER( tag) struct Finalizer_ ## tag { ~Finalizer_ ## tag(); } static Finalizer_ ## tag ## _instance; Finalizer_ ## tag::~Finalizer_ ## tag(void) - - -//================================================================================================= -// Templates / meta-programming: - - -#if (__GNUC__ > 3) || (__GNUC__ >= 3 && __GNUC_MINOR__ >= 4) -//#define TEMPLATE_FAIL (fprintf(stderr, "TEMPLATE FAIL!\n"), exit(1)) -template struct STATIC_ASSERTION_FAILURE; -template <> struct STATIC_ASSERTION_FAILURE{}; -#define TEMPLATE_FAIL STATIC_ASSERTION_FAILURE() -#else -#define TEMPLATE_FAIL TemplateFail() -#endif - -#define ASSERT_SUBTYPE(child, base) \ - static child * const __dummy_child = NULL; \ - static base * const __dummy_base = __dummy_child; - -#define AS(type) (*static_cast(this)) // (dangerous trick) - -struct True_T { }; -struct False_T { }; -struct Undef_T { }; - -#define COMMA , - -#define DEFAULT_EXTEND(Class, Method, RetType, Formals, Params, Dummies, Default) \ - static Undef_T Method(Formals) { return Undef_T(); } \ - template \ - struct Extend_ ## Class : Parent { \ - RetType new_ ## Method(RetType* , Formals) { return Method(Params); } \ - RetType new_ ## Method(Undef_T* , Formals) { Default } \ - RetType new_ ## Method(Formals) { \ - return new_ ## Method((typeof(peek(Dummies))*)NULL, Params); } \ - }; - - -//================================================================================================= -// Basic types: - - -typedef signed char schar; -typedef unsigned char uchar; -typedef unsigned int uint; -typedef unsigned long ulong; - -typedef const char cchar; - -typedef short int16; -typedef unsigned short uint16; -typedef int int32; -typedef unsigned uint32; -#ifdef __GNUC__ -typedef long long int64; -typedef unsigned long long uint64; -typedef __PTRDIFF_TYPE__ intp; -typedef unsigned __PTRDIFF_TYPE__ uintp; -#define I64_fmt "lld" -#else -// (assume Windows compiler) -typedef INT64 int64; -typedef UINT64 uint64; -typedef INT_PTR intp; -typedef UINT_PTR uintp; -#define I64_fmt "I64d" -#endif - -#ifdef __LP64__ -#define LP64 // LP : int=32 long,ptr=64 (unix model -- the windows model is LLP : int,long=32 ptr=64) -#endif - - -//================================================================================================= -// 'malloc()'-style memory allocation -- never returns NULL; aborts instead: - - -#ifdef NoExceptions - #define memAssert(cond) assert(cond) -#else - class Exception_MemOut {}; - #define memAssert(cond) if (!(cond)) throw Exception_MemOut() -#endif - -template macro T* xmalloc(size_t size) ___malloc; -template macro T* xmalloc(size_t size) { - T* tmp = (T*)malloc(size * sizeof(T)); - memAssert(size == 0 || tmp != NULL); - return tmp; } - -template macro T* xrealloc(T* ptr, size_t size) ___malloc; -template macro T* xrealloc(T* ptr, size_t size) { - T* tmp = (T*)realloc((void*)ptr, size * sizeof(T)); - memAssert(size == 0 || tmp != NULL); - return tmp; } - -template macro void xfree(T* ptr) { - if (ptr != NULL) free((void*)ptr); } - - -//================================================================================================= -// Bit macros: - - -// Signed min/max -- These are only 31 bit safe (or 63 bits; one less than the word size). -// To get the 32nd bit (64th) right you need "subtract with borrow", which C does not support. -// -macro int imin(int x, int y) { - int mask = (x-y) >> (sizeof(int)*8-1); - return (x&mask) + (y&(~mask)); } - -macro int imax(int x, int y) { - int mask = (y-x) >> (sizeof(int)*8-1); - return (x&mask) + (y&(~mask)); } - -macro int isign(int x) { - return (x >> (sizeof(int)*8-1)) & 1; } - - -//================================================================================================= -// Automatic disposal of C arrays: - - -template -class Free { - T* vec; -public: - Free(T* vec_) { vec = vec_; } - ~Free(void) { free(vec); } - operator T* (void) { return vec; } -}; - -#define sFree(cstr) ((cchar*)Free(cstr)) // (string disposal (cchar*)) -- NOTE! Unsafe in new C++ standard! - - -//================================================================================================= -// Strings and Show: - - -macro char* Xstrdup(cchar* src) ___malloc; -macro char* Xstrdup(cchar* src) { - int size = strlen(src)+1; - char* tmp = xmalloc(size); - memcpy(tmp, src, size); - return tmp; } -#define xstrdup(s) Xstrdup(s) - -macro char* xstrndup(cchar* src, int len) ___malloc; -macro char* xstrndup(cchar* src, int len) { - int size; for (size = 0; size < len && src[size] != '\0'; size++); - char* tmp = xmalloc(size+1); - memcpy(tmp, src, size); tmp[size] = '\0'; - return tmp; } - -#include "String.h" - -char* nsprintf (cchar* format, ...) ___format(printf, 1, 2) ___malloc; -char* strnum (int num) ___malloc; -char* strtokr (char** src, cchar* seps); -int fileSize (cchar* filename); -char* readFile (cchar* filename, int* size_ = NULL); -char* readFile (FILE* in, int* size_ = NULL); -char* extendedReadFile(cchar* sources, int* size = NULL, bool output_error = true); -void writeFile(cchar* filename, cchar* data, int size); - -#define tempf(format, args...) sFree(nsprintf(format , ## args)) - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template macro String show(const T& t) { return t.show(); } - -macro String show(int x) { return sown(strnum(x)); } -macro String show(cchar* x) { return scopy(x); } -macro String show(char* x) { return scopy(x); } - -#define showf(format, args...) sown(nsprintf(format , ## args)) - - -//================================================================================================= -// Random numbers: - - -// Returns a random float 0 <= x < 1. Seed must never be 0. -macro double drand(double& seed) { - seed *= 1389796; - int q = (int)(seed / 2147483647); - seed -= (double)q * 2147483647; - return seed / 2147483647; } - -// Returns a random integer 0 <= x < size. Seed must never be 0. -macro int irand(double& seed, int size) { - return (int)(drand(seed) * size); } - - -//================================================================================================= -// 'Pair': - - -template -struct Pair { - typedef Fst Fst_t; - typedef Snd Snd_t; - - Fst fst; - Snd snd; - - Pair(void) { } - Pair(const Fst& x, const Snd& y) : fst(x), snd(y) { } - - template - Pair(const Pair& p) : fst(p.fst), snd(p.snd) { } - - void split(Fst& out_fst, Snd& out_snd) { out_fst = fst; out_snd = snd; } -}; - - -template -inline bool operator == (const Pair& x, const Pair& y) { - return (x.fst == y.fst) && (x.snd == y.snd); } - -template -inline bool operator < (const Pair& x, const Pair& y) { - return x.fst < y.fst || - (!(y.fst < x.fst) && x.snd < y.snd); } - -template -inline Pair Pair_new(const Fst& x, const Snd& y) { - return Pair(x, y); } - - -//================================================================================================= -// 'vec' -- automatically resizable arrays (via 'push()' method): - - -// NOTE! Don't use this vector on datatypes that cannot be moved with 'memcpy'. - -template -class vec { - T* data; - int sz; - int cap; - - void init(int size, const T& pad); - void grow(int min_cap); - -public: - // Types: - typedef int Key; - typedef T Datum; - - // Constructors: - vec(void) : data(NULL) , sz(0) , cap(0) { } - 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(T* array, int size) : data(array), sz(size), cap(size) { } // (takes ownership of array -- will be deallocated with 'xfree()') - ~vec(void) { clear(true); } - - // Ownership of underlying array: - T* release (void) { T* ret = data; data = NULL; sz = 0; cap = 0; return ret; } - operator T* (void) { return data; } // (unsafe but convenient) - operator const T* (void) const { 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 pop (void) { sz--, data[sz].~T(); } - void growTo (int size); - void growTo (int size, const T& pad); - void clear (bool dealloc = false); - - // Stack interface: - void push (void) { if (sz == cap) grow(sz+1); new (&data[sz]) T() ; sz++; } - void push (const T& elem) { if (sz == cap) grow(sz+1); new (&data[sz]) T(elem); sz++; } - const T& last (void) const { return data[sz-1]; } - T& last (void) { return data[sz-1]; } - - // Vector interface: - #ifdef PARANOID - const T& operator [] (int index) const { assert((uint)index < (uint)sz); return data[index]; } - T& operator [] (int index) { assert((uint)index < (uint)sz); return data[index]; } - #else - const T& operator [] (int index) const { return data[index]; } - T& operator [] (int index) { return data[index]; } - #endif - - // Don't allow copying: - vec& operator = (vec& other) { TEMPLATE_FAIL; } - vec (vec& other) { TEMPLATE_FAIL; } - - // Duplicatation: - void copyTo(vec& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) new (©[i]) T(data[i]); } - void moveTo(vec& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; } - - // Show: - String show(void) const { - String result = showf("%d/%d @ %p :", sz, cap, data); - for (int i = 0; i < sz; i++) result = result + sref(" ") + sref("{") + ::show(data[i]) + sref("}"); - return result; } -}; - -template -void vec::grow(int min_cap) { - if (min_cap <= cap) return; - if (cap == 0) cap = (min_cap >= 16) ? min_cap : 16; - else do cap = cap*2 + 16; while (cap < min_cap); - data = xrealloc(data, cap); } - -template -void vec::growTo(int size, const T& pad) { - if (sz >= size) return; - grow(size); - for (int i = sz; i < size; i++) new (&data[i]) T(pad); - sz = size; } - -template -void vec::growTo(int size) { - if (sz >= size) return; - grow(size); - for (int i = sz; i < size; i++) new (&data[i]) T(); - sz = size; } - -template -void vec::clear(bool dealloc) { - if (data != NULL){ - for (int i = 0; i < sz; i++) data[i].~T(); - sz = 0; - if (dealloc) xfree(data), data = NULL, cap = 0; } } - - -//================================================================================================= -// Relation operators -- extend definitions from '==' and '<' - - -#ifndef __SGI_STL_INTERNAL_RELOPS // (be aware of SGI's STL implementation...) -#define __SGI_STL_INTERNAL_RELOPS -template macro bool operator != (const T& x, const T& y) { return !(x == y); } -template macro bool operator > (const T& x, const T& y) { return y < x; } -template macro bool operator <= (const T& x, const T& y) { return !(y < x); } -template macro bool operator >= (const T& x, const T& y) { return !(x < y); } -#endif - - -//================================================================================================= -// Lifted booleans: - - -class lbool { - int value; - - -public: - explicit lbool(int v) : value(v) { } - lbool() : value(0) { } - lbool(bool x) : value((int)x*2-1) { } - int toInt(void) const { return value; } - - bool operator == (const lbool& other) const { return value == other.value; } - bool operator != (const lbool& other) const { return value != other.value; } - lbool operator ~ (void) const { return lbool(-value); } - - friend int toInt (lbool l) { return l.toInt(); } - // friend lbool toLbool(int v); - friend char name (lbool l) { static char name[4] = {'!','0','?','1'}; int x = l.value; x = 2 + ((x >> (sizeof(int)*8-2)) | (x & ~(1 << (sizeof(int)*8-1)))); return name[x]; } -}; - -//lbool toLbool(int v) { return lbool(v); } - -const lbool l_True = lbool(1);//toLbool( 1); -const lbool l_False = lbool(-1);//toLbool(-1); -const lbool l_Undef = lbool(0);//toLbool( 0); -const lbool l_Error = lbool(1 << (sizeof(int)*8-1));//toLbool(1 << (sizeof(int)*8-1)); - - - - -//================================================================================================= -// Resource usage: - - -#include -#include -#include - -macro double cpuTime(void) { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; } - -macro double realTime(void) { - struct ntptimeval t; - ntp_gettime(&t); - return (double)t.time.tv_sec + (double)t.time.tv_usec / 1000000; } - -int64 memUsed (void); -int64 memResident(void); -int64 memPhysical(void); - - -//================================================================================================= -// Other: - - -template -macro void swp(T& x, T& y) { // 'swap' is used by STL - T tmp = x; x = y; y = tmp; } - - -template -class Restore { - T* variable_ptr; - T old_value; -public: - Restore(T& x) : variable_ptr(&x), old_value(x) {} - ~Restore(void) { *variable_ptr = old_value; } -}; - - -//================================================================================================= - -#endif diff --git a/sources/SatElite/ForMani/Global/Global.od b/sources/SatElite/ForMani/Global/Global.od deleted file mode 100644 index ac5686755f739826e70d95a024a001d285924428..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41896 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.leaf) ? strlen(s->leaf.text) - : slen(s->node.left) + slen(s->node.right); } - - -static -void stext_(String s, char** result) -{ - if (s->type.leaf){ - char* p = s->leaf.text; - while (*p != '\0') - *(*result)++ = *p++; - }else{ - stext_(s->node.left , result); - stext_(s->node.right, result); - } -} - -char* stext(String s) -{ - char* result = xmalloc(slen(s) + 1); - char* tmp = result; - stext_(s, &tmp); - *tmp = '\0'; - return result; -} - - -static -void sfree1(String s) -{ - if (s->type.leaf){ - if (s->leaf.owns) - xfree(s->leaf.text); - }else{ - if (s->node.left ->type.disposed) s->node.left = NULL; - else sfree1(s->node.left); - - if (s->node.right->type.disposed) s->node.right = NULL; - else sfree1(s->node.right); - } - s->type.disposed = true; -} - -static -void sfree2(String s) -{ - if (!s->type.leaf){ - if (s->node.left != (String_t*)NULL) sfree2(s->node.left ); - if (s->node.right != (String_t*)NULL) sfree2(s->node.right); - } - String_delete(s); -} - -void sfree(String s) -{ - sfree1(s); - sfree2(s); -} diff --git a/sources/SatElite/ForMani/Global/String.h b/sources/SatElite/ForMani/Global/String.h deleted file mode 100644 index 4774413..0000000 --- a/sources/SatElite/ForMani/Global/String.h +++ /dev/null @@ -1,107 +0,0 @@ -/************************************************************************************************** - -STRING -- Department of Computer Science, Chalmers University of Technology 2002. - -File..: String.h -Author: Niklas Een, een@cs.chalmers.se -Descr.: Minimal ADT for strings. - -**************************************************************************************************/ - -#ifndef String_h -#define String_h - -//================================================================================================= - - -struct String_t; -extern String_t String_empty; -struct String { - String_t* ptr; - String(String_t* p) { ptr = p; } - String(void) { ptr = &String_empty; } - - String_t* operator -> (void) const { return ptr; } - String_t* operator = (String_t* p) { return ptr = p; } - bool operator == (String s) const { return ptr == s.ptr; } - bool operator != (String s) const { return ptr != s.ptr; } - bool operator == (String_t* p) const { return ptr == p; } - bool operator != (String_t* p) const { return ptr != p; } -}; - - -struct String_t { - struct { - unsigned leaf : 1; - unsigned disposed : 1; - } type; - union { - struct { - char* text; - bool owns; - } leaf; - struct { - String_t* left; - String_t* right; - } node; - }; -}; - - -static -String String_leaf(char* text, bool owns) { - String tmp(new String_t); - tmp->type.leaf = true; - tmp->type.disposed = false; - tmp->leaf.text = text; - tmp->leaf.owns = owns; - return tmp; } - -static -String String_node(String left, String right) { - String tmp(new String_t); - tmp->type.leaf = false; - tmp->type.disposed = false; - tmp->node.left = left .ptr; - tmp->node.right = right.ptr; - return tmp; } - -static void String_delete(String s) ___unused; -static -void String_delete(String s) { - if (s.ptr != &String_empty) - delete s.ptr; } - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -inline String scopy(const char* text) { - return String_leaf(xstrdup(text), true); } - -inline String sref(const char* text) { - return String_leaf(const_cast(text), false); } - -inline String sown(char* text) { - return String_leaf(text, true); } - -inline String scat(String s1, String s2) { - return String_node(s1, s2); } - -inline String operator + (String s1, String s2) { - return scat(s1, s2); } - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int slen (String s); -char* stext(String s); -void sfree(String s); - -inline char* stextf(String s) - { char* tmp = stext(s); sfree(s); return tmp; } - -#define stemp(s) ((char*)Free(stext(s))) -#define stempf(s) ((char*)Free(stextf(s))) - - -//================================================================================================= - -#endif diff --git a/sources/SatElite/ForMani/Global/depend.mak b/sources/SatElite/ForMani/Global/depend.mak deleted file mode 100644 index aa0b820..0000000 --- a/sources/SatElite/ForMani/Global/depend.mak +++ /dev/null @@ -1,85 +0,0 @@ -Global.o: Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.C String.h -String.o: String.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.h -Global.o: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.o: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h -Global.op: Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.C String.h -String.op: String.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.h -Global.op: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.op: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h -Global.od: Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.C String.h -String.od: String.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.h -Global.od: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.od: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h -Global.or: Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.C String.h -String.or: String.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.h -Global.or: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.or: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h -Global.ox: Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.C String.h -String.ox: String.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - String.h -Global.ox: \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.C -File.ox: /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.C \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/Global.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/Global/String.h \ - /tmp/sat2005_submission/SatELite_submission/ForMani/ADTs/File.h diff --git a/sources/SatElite/ForMani/depend.mak b/sources/SatElite/ForMani/depend.mak deleted file mode 100644 index e69de29..0000000 diff --git a/sources/SatElite/ForMani/dummy.mak b/sources/SatElite/ForMani/dummy.mak deleted file mode 100644 index e69de29..0000000 diff --git a/sources/SatElite/ForMani/options.mak b/sources/SatElite/ForMani/options.mak deleted file mode 100644 index 61b52f2..0000000 --- a/sources/SatElite/ForMani/options.mak +++ /dev/null @@ -1,11 +0,0 @@ -OPTIMIZE := -O3 -OPTIMORE := -O10 -foptimize-sibling-calls -finline-functions -fcse-follow-jumps -fcse-skip-blocks -frerun-cse-after-loop -frerun-loop-opt -fgcse # -fomit-frame-pointer -INCLUDES := $(FM_INCLUDE) -include $(FM)/Global/Global.h -I$(FM)/ADTs -I$(FM)/Lib/Include -I$(PWD) -OBJS := $(sort $(addsuffix .o, $(basename $(wildcard *.C *.l *.env)))) -ifdef EXTENSION - XOBJS := $(sort $(addsuffix .o, $(basename $(wildcard ext_$(EXTENSION)/*.C ext_$(EXTENSION)/*.def ext_$(EXTENSION)/*.l ext_$(EXTENSION)/*.env)))) - OBJS := $(filter-out $(notdir $(XOBJS)), $(OBJS)) $(XOBJS) -endif -GOBJS := $(FM)/Global/Global.o $(FM)/ADTs/File.o -EXEC := $(notdir $(shell pwd)) -DEP_FILES := $(addsuffix .C, $(basename $(OBJS))) diff --git a/sources/SatElite/ForMani/standard.mak b/sources/SatElite/ForMani/standard.mak deleted file mode 100644 index a8b424d..0000000 --- a/sources/SatElite/ForMani/standard.mak +++ /dev/null @@ -1,2 +0,0 @@ -include $(FM)/options.mak -include $(FM)/template.mak diff --git a/sources/SatElite/ForMani/template.mak b/sources/SatElite/ForMani/template.mak deleted file mode 100644 index cb4ed97..0000000 --- a/sources/SatElite/ForMani/template.mak +++ /dev/null @@ -1,125 +0,0 @@ -### This file assumes OPTIMIZE, OPTIMOR, INCLUDES, OBJS, GOBJS, EXEC, DEP_FILES to be defined. -### (OBJS are object files generated from ".C" files) - - -## Compilation: -## -COMPILE_STANDARD = -m32 -ggdb -D DEBUG $(OPTIMIZE) $(DEBUG) $(INCLUDES) $(FM_COPTS) -COMPILE_PROFILE = -m32 -pg -ggdb -D DEBUG $(OPTIMIZE) $(DEBUG) $(INCLUDES) $(FM_COPTS) -COMPILE_DEBUG = -m32 -ggdb -D DEBUG -D PARANOID -O0 $(DEBUG) $(INCLUDES) $(FM_COPTS) -COMPILE_RELEASE = -m32 -D NDEBUG -D RELEASE $(OPTIMORE) $(INCLUDES) $(FM_COPTS) -COMPILE_EXTRA = -m32 $(COMPILE_STANDARD) -cxxlib-icc - -compile-C = if [ "$(notdir $<)" = "$<" ] || extdir "$<"; then echo Compiling: $<; g++ -c -Wall $(COMPILE_STANDARD) -o $@ $<; else echo Compiling: $<; (if [ -e $(dir $<)/Makefile ]; then make -C $(dir $<) $(notdir $@); else make -f $(FM)/standard.mak -C $(dir $<) $(notdir $@); fi) ; fi -compile-Cp = if [ "$(notdir $<)" = "$<" ]; then echo Compiling profile: $<; g++ -c -Wall $(COMPILE_PROFILE) -o $@ $<; else echo Compiling profile: $<; (if [ -e $(dir $<)/Makefile ]; then make -C $(dir $<) $(notdir $@); else make -f $(FM)/standard.mak -C $(dir $<) $(notdir $@); fi) ; fi -compile-Cd = if [ "$(notdir $<)" = "$<" ]; then echo Compiling debug: $<; g++ -c -Wall $(COMPILE_DEBUG) -o $@ $<; else echo Compiling debug: $<; (if [ -e $(dir $<)/Makefile ]; then make -C $(dir $<) $(notdir $@); else make -f $(FM)/standard.mak -C $(dir $<) $(notdir $@); fi) ; fi -compile-Cr = if [ "$(notdir $<)" = "$<" ]; then echo Compiling release: $<; g++ -c -Wall $(COMPILE_RELEASE) -o $@ $<; else echo Compiling release: $<; (if [ -e $(dir $<)/Makefile ]; then make -C $(dir $<) $(notdir $@); else make -f $(FM)/standard.mak -C $(dir $<) $(notdir $@); fi) ; fi -compile-Cx = if [ "$(notdir $<)" = "$<" ]; then echo Compiling extra: $<; icc -c $(COMPILE_EXTRA) -o $@ $<; else echo Compiling extra: $<; (if [ -e $(dir $<)/Makefile ]; then make -C $(dir $<) $(notdir $@); else make -f $(FM)/standard.mak -C $(dir $<) $(notdir $@); fi) ; fi - -%.o: %.C - @$(compile-C) -%.op: %.C - @$(compile-Cp) -%.od: %.C - @$(compile-Cd) -%.or: %.C - @$(compile-Cr) -%.ox: %.C - @$(compile-Cx) - - -%.C : %.def $(FM)/Bin/BuildOptions - @echo Building : $(notdir $@) - @$(FM)/Bin/BuildOptions $< - -%.C : %.env $(FM)/Bin/BuildEnv - @echo Building : $(notdir $@) - @$(FM)/Bin/BuildEnv $< - -%.C : %.l - @echo Flexing : $(notdir $<) - flex -o$@ -P$(basename $(notdir $<))_ $< - - -## Build/Clean: -## -LFLAGS = -m32 $(FM_LOPTS) -L $(FM)/Lib $(addprefix -l, $(LIBS)) $(addprefix -l, $(CLIBS)) -LIBFILES = $(addprefix $(FM)/Lib/lib, $(addsuffix .a, $(LIBS))) - -$(EXEC) : $(OBJS) $(GOBJS) $(LIBFILES) - @echo Linking... - @g++ -ggdb -Wall $(OBJS) $(GOBJS) -o $(EXEC) $(LFLAGS) - -$(EXEC)_purify : $(GOBJS) $(OBJS) $(LIBFILES) - @echo Linking purify version... - @purify g++ -ggdb -Wall $(GOBJS) $(OBJS) -o $(EXEC)_purify $(LFLAGS) - -$(EXEC)_profile : $(addsuffix .op, $(basename $(GOBJS) $(OBJS))) $(LIBFILES) - @echo Linking profile version... - @g++ -ggdb -pg -Wall $(addsuffix .op, $(basename $(GOBJS) $(OBJS))) -o $(EXEC)_profile $(LFLAGS) - -$(EXEC)_debug : $(addsuffix .od, $(basename $(GOBJS) $(OBJS))) $(LIBFILES) - @echo Linking debug version... - @g++ -ggdb -Wall $(addsuffix .od, $(basename $(GOBJS) $(OBJS))) -o $(EXEC)_debug $(LFLAGS) - -$(EXEC)_release : $(addsuffix .or, $(basename $(GOBJS) $(OBJS))) $(LIBFILES) - @echo Linking release version... - g++ --static -O3 -Wall $(addsuffix .or, $(basename $(GOBJS) $(OBJS))) -o $(EXEC)_release $(LFLAGS) - -$(EXEC)_extra : $(addsuffix .ox, $(basename $(GOBJS) $(OBJS))) $(LIBFILES) - @echo Linking extra version... - icc -cxxlib-icc --static -ggdb $(addsuffix .ox, $(basename $(GOBJS) $(OBJS))) -o $(EXEC)_extra $(LFLAGS) - -.PHONY : purify -pure: $(EXEC)_purify -.PHONY : p -p: $(EXEC)_profile -.PHONY : d -d: $(EXEC)_debug -.PHONY : r -r: $(EXEC)_release -.PHONY : x -x: $(EXEC)_extra - -.PHONY : clean -clean: - @rm -f $(CLEAN) depend.mak \ - $(EXEC) $(EXEC)_purify $(EXEC)_profile $(EXEC)_debug $(EXEC)_release \ - $(OBJS) \ - $(addsuffix .op, $(basename $(OBJS))) \ - $(addsuffix .od, $(basename $(OBJS))) \ - $(addsuffix .or, $(basename $(OBJS))) \ - $(addsuffix .ox, $(basename $(OBJS))) - -.PHONY : realclean -realclean: - @rm -f $(CLEAN) depend.mak \ - $(EXEC) $(EXEC)_purify $(EXEC)_profile $(EXEC)_debug $(EXEC)_release \ - $(GOBJS) $(OBJS) \ - $(addsuffix .op, $(basename $(GOBJS) $(OBJS))) \ - $(addsuffix .od, $(basename $(GOBJS) $(OBJS))) \ - $(addsuffix .or, $(basename $(GOBJS) $(OBJS))) \ - $(addsuffix .ox, $(basename $(GOBJS) $(OBJS))) - - -## Dependencies: -## -define make-depend - @echo "Generating dependencies" - @g++ -MM $(FM_COPTS) $(INCLUDES) $(addsuffix .C, $(basename $(OBJS) $(GOBJS))) > dummy.mak - @cp dummy.mak depend.mak - @sed "s/o:/op:/" dummy.mak >> depend.mak - @sed "s/o:/od:/" dummy.mak >> depend.mak - @sed "s/o:/or:/" dummy.mak >> depend.mak - @sed "s/o:/ox:/" dummy.mak >> depend.mak - @rm -f dummy.mak -endef - -.PHONY : depend -depend : $(DEP_FILES) - $(make-depend) - -depend.mak : $(DEP_FILES) - $(make-depend) - -include depend.mak diff --git a/sources/SatElite/SatELite/BcnfWriter.iC b/sources/SatElite/SatELite/BcnfWriter.iC deleted file mode 100644 index 6bbcb9d..0000000 --- a/sources/SatElite/SatELite/BcnfWriter.iC +++ /dev/null @@ -1,79 +0,0 @@ -// -// NOTE! Must include "SolverTypes.h" before including this file. -// - -#define BCNF_CHUNK_LIMIT 1048576 - - -//================================================================================================= -// BCNF Writer: - - -class BcnfWriter { - FILE* out; - int n_vars; - int n_clauses; - int chunk_sz; - int* chunk; - -public: - int stated_n_vars; // }- The "p cnf" line. - int stated_n_clauses; // } - - BcnfWriter(cchar* output_file); - ~BcnfWriter(void); - - void addClause(vec& c); - int nVars (void) { return n_vars; } - int nClauses(void) { return n_clauses; } -}; - - -BcnfWriter::BcnfWriter(cchar* output_file) - : n_vars(0), n_clauses(0), chunk_sz(1), stated_n_vars(-1), stated_n_clauses(-1) -{ - out = fopen(output_file, "w+b"); - if (out == NULL) fprintf(stderr, "ERROR! Could not open file for writing: %s\n", output_file), exit(2); // <<= Exception handling - fputc(0, out); fputc(0, out); fputc(0, out); fputc(0, out); // Room for header: "BCNF" - fputc(0, out); fputc(0, out); fputc(0, out); fputc(0, out); // Room for byte-order: 1,2,3,4 - fputc(0, out); fputc(0, out); fputc(0, out); fputc(0, out); // Room for #variables - fputc(0, out); fputc(0, out); fputc(0, out); fputc(0, out); // Room for #clauses - - chunk = xmalloc(BCNF_CHUNK_LIMIT); -} - - -BcnfWriter::~BcnfWriter(void) -{ - chunk[0] = chunk_sz; - chunk[chunk_sz++] = -1; - fwrite(chunk, 4, chunk_sz, out); - xfree(chunk); - - fflush(out); - rewind(out); - int byte_order = 0x01020304; - fputc('B', out); fputc('C', out); fputc('N', out); fputc('F', out); - fwrite(&byte_order, 1, 4, out); - fwrite(&n_vars , 1, 4, out); - fwrite(&n_clauses , 1, 4, out); - fclose(out); -} - - -void BcnfWriter::addClause(vec& c) -{ - n_clauses++; - - if (chunk_sz + 3 + c.size() >= BCNF_CHUNK_LIMIT){ // leave room for final terminator size ("-1") and the chunk size itself (not really part of the chunk, but just in case). - chunk[0] = chunk_sz; - chunk[chunk_sz++] = -1; - fwrite(chunk, 4, chunk_sz, out); - chunk_sz = 1; } - - assert(chunk_sz + 3 + c.size() < BCNF_CHUNK_LIMIT); - chunk[chunk_sz++] = c.size(); - for (int i = 0; i < c.size(); i++) - chunk[chunk_sz++] = index(c[i]), - n_vars = max(n_vars, var(c[i]) + 1); -} diff --git a/sources/SatElite/SatELite/Heap.h b/sources/SatElite/SatELite/Heap.h deleted file mode 100644 index 1899831..0000000 --- a/sources/SatElite/SatELite/Heap.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __HEAP__ -#define __HEAP__ - -static inline int left (int i) { return i * 2; } -static inline int right(int i) { return i * 2 + 1; } -static inline int parent(int i) { return i / 2; } - -template -class Heap { - public: - C comp; - vec heap; // heap of ints - vec indices; // int -> index in heap - - inline void percolateUp(int i) - { - int x = heap[i]; - while (parent(i) != 0 && comp(x,heap[parent(i)])){ - heap[i] = heap[parent(i)]; - indices[heap[i]] = i; - i = parent(i); - } - heap[i] = x; - indices[x] = i; - } - - inline void percolateDown(int i) - { - int x = heap[i]; - while (left(i) < heap.size()){ - int child = right(i) < heap.size() && comp(heap[right(i)],heap[left(i)]) ? right(i) : left(i); - if (comp(x,heap[child])) break; - heap[i] = heap[child]; - indices[heap[i]] = i; - i = child; - } - heap[i] = x; - indices[x] = i; - } - - bool ok(int n) { return n >= 0 && n < (int)indices.size(); } - - public: - Heap(C c) : comp(c) { heap.push(-1); } - - void setBounds (int size) { assert(size >= 0); indices.growTo(size,0); } - bool inHeap (int n) { assert(ok(n)); return indices[n] != 0; } - void increase (int n) { assert(ok(n)); assert(inHeap(n)); percolateUp(indices[n]); } - bool empty (void) { return heap.size() == 1; } - - void insert(int n) { - assert(ok(n)); - indices[n] = heap.size(); - heap.push(n); - percolateUp(indices[n]); - } - - int getmin(void) { - int r = heap[1]; - int q = heap[1] = heap.last(); heap.pop(); - indices[r] = 0; - indices[q] = 1; - if (heap.size() > 1) percolateDown(1); - return r; - } - - int peekmin(void) { return heap[1]; } - - bool heapProperty(void) { return heapProperty(1); } - bool heapProperty(int i) { - return (size_t)i >= heap.size() || - ((parent(i) == 0 || !comp(heap[i],heap[parent(i)])) && - heapProperty(left(i)) && heapProperty(right(i))); - } -}; - -#endif diff --git a/sources/SatElite/SatELite/Main.C b/sources/SatElite/SatELite/Main.C deleted file mode 100644 index 3b9488a..0000000 --- a/sources/SatElite/SatELite/Main.C +++ /dev/null @@ -1,568 +0,0 @@ -/************************************************************************************************** - -Main.C -- (C) Niklas Een 2005 - -Read a DIMACS or BCNF file and apply the SAT-solver to it. - -**************************************************************************************************/ - -#ifndef SAT_LIVE -#ifndef NDEBUG -#define VERIFY_MODEL -#endif -#endif - -#include "Main.h" -#include "Solver.h" -#include -#include -#include -#include "File.h" - - -//================================================================================================= -// Options: - - -static cchar* doc = - "SatELite [OUTPUTS: [ []]]\n" - " options: {+,-}{cs1,csk,ve,s0,s1,s2,r,(de,ud,h1)=ve+,pl,as,all,det, pre,ext,mod}\n" - " and: --{help,defaults,verbosity=}\n" -; - - -#if 0 -bool opt_confl_1sub = false; -bool opt_confl_ksub = false; -bool opt_var_elim = false; -bool opt_0sub = false; -bool opt_1sub = false; -bool opt_2sub = false; -bool opt_repeated_sub = false; -bool opt_def_elim = false; -bool opt_unit_def = false; -bool opt_hyper1_res = false; -bool opt_pure_literal = false; -bool opt_asym_branch = false; -bool opt_keep_all = false; -bool opt_no_random = false; -bool opt_pre_sat = false; -bool opt_ext_sat = false; - -bool opt_niver = false; -#else -bool opt_confl_1sub = true; -bool opt_confl_ksub = false; -bool opt_var_elim = true; -bool opt_0sub = true; -bool opt_1sub = true; -bool opt_2sub = false; -bool opt_repeated_sub = false; -bool opt_def_elim = false; -bool opt_unit_def = false; -bool opt_hyper1_res = false; -bool opt_pure_literal = false; -bool opt_asym_branch = false; -bool opt_keep_all = false; -bool opt_no_random = false; -bool opt_pre_sat = false; -bool opt_ext_sat = false; - -bool opt_niver = false; -#endif - -cchar* input_file = NULL; -cchar* output_file = NULL; // (doubles as result input from MiniSat) -cchar* varmap_file = NULL; -cchar* elimed_file = NULL; -cchar* model_file = NULL; -int verbosity = 1; - - -void parseOptions(int argc, char** argv) -{ - vec args; // Non-options - - for (int i = 1; i < argc; i++){ - char* arg = argv[i]; - if (arg[0] == '-' || arg[0] == '+'){ - if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) - fprintf(stderr, "%s", doc), exit(0); - - else if (strncmp(arg, "--verbosity=", 12) == 0) verbosity = atoi(arg+12); - else if (strcmp(arg, "-v0") == 0) verbosity = 0; - else if (strcmp(arg, "-v1") == 0) verbosity = 1; - else if (strcmp(arg, "-v2") == 0) verbosity = 2; - - else if (strcmp(arg, "--niver") == 0){ - opt_var_elim = false; - opt_0sub = false; - opt_1sub = false; - opt_pre_sat = true; - opt_var_elim = true; - opt_niver = true; - } - - else if (strcmp(arg, "--plain") == 0 || strcmp(arg, "-") == 0){ - opt_confl_1sub = false; - opt_confl_ksub = false; - opt_var_elim = false; - opt_0sub = false; - opt_1sub = false; - opt_2sub = false; - opt_repeated_sub = false; - opt_def_elim = false; - opt_unit_def = false; - opt_hyper1_res = false; - opt_pure_literal = false; - opt_asym_branch = false; - opt_keep_all = false; - opt_no_random = false; - opt_pre_sat = false; - opt_ext_sat = false; - } - - else if (strcmp(arg, "--defaults") == 0 || strcmp(arg, "-d") == 0) - printf("%c""cs1" " (confl_1sub )\n" - "%c""csk" " (confl_ksub )\n" - "%c""ve " " (var_elim )\n" - "%c""s0 " " (0sub )\n" - "%c""s1 " " (1sub )\n" - "%c""s2 " " (2sub )\n" - "%c""r " " (repeated_sub)\n" - "%c""de " " (def_elim )\n" - "%c""ud " " (unit_def )\n" - "%c""h1 " " (hyper1_res )\n" - "%c""pl " " (pure_literal)\n" - "%c""as " " (asym_branch )\n" - "%c""all" " (keep_all )\n" - "%c""det" " (no_random )\n" - "%c""pre" " (pre_sat )\n" - "%c""ext" " (ext_sat )\n" - , opt_confl_1sub ? '+' : '-' - , opt_confl_ksub ? '+' : '-' - , opt_var_elim ? '+' : '-' - , opt_0sub ? '+' : '-' - , opt_1sub ? '+' : '-' - , opt_2sub ? '+' : '-' - , opt_repeated_sub ? '+' : '-' - , opt_def_elim ? '+' : '-' - , opt_unit_def ? '+' : '-' - , opt_hyper1_res ? '+' : '-' - , opt_asym_branch ? '+' : '-' - , opt_pure_literal ? '+' : '-' - , opt_keep_all ? '+' : '-' - , opt_no_random ? '+' : '-' - , opt_pre_sat ? '+' : '-' - , opt_ext_sat ? '+' : '-' - ), - exit(0); - - else if (strcmp(arg+1, "cs1") == 0) opt_confl_1sub = (arg[0] != '-'); - else if (strcmp(arg+1, "csk") == 0) opt_confl_ksub = (arg[0] != '-'); - else if (strcmp(arg+1, "ve" ) == 0) opt_var_elim = (arg[0] != '-'); - else if (strcmp(arg+1, "s0" ) == 0) opt_0sub = (arg[0] != '-'); - else if (strcmp(arg+1, "s1" ) == 0) opt_1sub = (arg[0] != '-'); - else if (strcmp(arg+1, "s2" ) == 0) opt_2sub = (arg[0] != '-'); - else if (strcmp(arg+1, "r" ) == 0) opt_repeated_sub = (arg[0] != '-'); - else if (strcmp(arg+1, "de" ) == 0) opt_def_elim = (arg[0] != '-'); - else if (strcmp(arg+1, "ud" ) == 0) opt_unit_def = (arg[0] != '-'); - else if (strcmp(arg+1, "h1" ) == 0) opt_hyper1_res = (arg[0] != '-'); - else if (strcmp(arg+1, "as" ) == 0) opt_asym_branch = (arg[0] != '-'); - else if (strcmp(arg+1, "pl" ) == 0) opt_pure_literal = (arg[0] != '-'); - else if (strcmp(arg+1, "all") == 0) opt_keep_all = (arg[0] != '-'); - else if (strcmp(arg+1, "det") == 0) opt_no_random = (arg[0] != '-'); - else if (strcmp(arg+1, "pre") == 0) opt_pre_sat = (arg[0] != '-'); - else if (strcmp(arg+1, "ext") == 0) opt_ext_sat = (arg[0] != '-'); - - else if (strcmp(arg+1, "ve+") == 0) opt_var_elim = opt_def_elim = opt_unit_def = opt_hyper1_res = true; - - else if (strncmp(arg, "+pre=", 5) == 0){ - opt_pre_sat = true; - output_file = arg + 5; } - - else if (strncmp(arg, "+mod=", 5) == 0){ - model_file = arg + 5; } - - else - fprintf(stderr, "ERROR! Invalid command line option: %s\n", argv[i]), exit(1); - - }else - args.push(arg); - } - - if (args.size() >= 1) - input_file = args[0]; - if (args.size() >= 2){ - opt_pre_sat = true; - if (output_file != NULL) fprintf(stderr, "ERROR! Only one output file can be specified.\n"), exit(1); - output_file = args[1]; } - if (args.size() >= 3) - varmap_file = args[2]; - if (args.size() >= 4) - elimed_file = args[3]; - else if (args.size() > 4) - fprintf(stderr, "ERROR! Too many files specified.\n"), exit(1); -} - - -//================================================================================================= -// BCNF Parser: - - -#define CHUNK_LIMIT 1048576 - -static void parse_BCNF(cchar* filename, Solver& S) -{ - FILE* in = fopen(filename, "rb"); - if (in == NULL) fprintf(stderr, "ERROR! Could not open file: %s\n", filename), exit(1); - - char header[16]; - fread(header, 1, 16, in); - if (strncmp(header, "BCNF", 4) != 0) fprintf(stderr, "ERROR! Not a BCNF file: %s\n", filename), exit(1); - if (*(int*)(header+4) != 0x01020304) fprintf(stderr, "ERROR! BCNF file in unsupported byte-order: %s\n", filename), exit(1); - - int n_vars = *(int*)(header+ 8); -// int n_clauses = *(int*)(header+12); - int* buf = xmalloc(CHUNK_LIMIT); - int buf_sz; - vec c; - - for (int i = 0; i < n_vars; i++) S.newVar(); - //S.setVars(n_vars); - - for(;;){ - int n = fread(&buf_sz, 4, 1, in); - if (n != 1) break; - assert(buf_sz <= CHUNK_LIMIT); - fread(buf, 4, buf_sz, in); - - int* p = buf; - while (*p != -1){ - int size = *p++; - c.clear(); - c.growTo(size); - for (int i = 0; i < size; i++) - c[i] = toLit(p[i]); - p += size; - - S.addClause(c); // Add clause. - } - } - - xfree(buf); - fclose(in); - //**/printf("MEM USED: %lld\n", memUsed()); -} - - -//================================================================================================= -// DIMACS Parser: - - -class FileBuffer { - File in; - int next; -public: - FileBuffer(cchar* input_file) : in(input_file, "rb") { - if (in.null()) fprintf(stderr, "ERROR! Could not open file for reading: %s\n", input_file), exit(1); - next = in.getCharQ(); } - ~FileBuffer() {} - int operator * () { return next; } - void operator ++ () { next = in.getCharQ(); } -}; - - -class StringBuffer { - cchar* ptr; - cchar* last; -public: - StringBuffer(cchar* text, int size) { ptr = text; last = ptr + size; } - ~StringBuffer() {} - int operator * () { return (ptr >= last) ? EOF : *ptr; } - void operator ++ () { ++ptr; } -}; - - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -template -static void skipWhitespace(B& in) { - while ((*in >= 9 && *in <= 13) || *in == 32) - ++in; } - -template -static void skipLine(B& in) { - for (;;){ - if (*in == EOF) return; - if (*in == '\n') { ++in; return; } - ++in; } } - -template -static int parseInt(B& in) { - int val = 0; - bool neg = false; - skipWhitespace(in); - if(*in == EOF) return 0; - 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; } - -template -static void readClause(B& in, Solver& S, vec& 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) ? Lit(var) : ~Lit(var) ); - } -} - -template -static bool match(B& in, char* str) { - for (; *str != 0; ++str, ++in) - if (*str != *in) - return false; - return true; -} - - -template -static void parse_DIMACS_main(B& in, Solver& S) { - vec lits; - for (;;){ - skipWhitespace(in); - if (*in == EOF) - break; - else if (*in == 'p'){ - if (match(in, "p cnf")){ - int vars = parseInt(in); - int clauses = parseInt(in); - if(clauses>4800000) { - printf("c num clauses = %d\n",clauses); - printf("c too many clauses .. no preprocessing\n"); - exit(11); - } - }else{ - reportf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3); - } - } - else if (*in == 'c' || *in == 'p') - skipLine(in); - else - readClause(in, S, lits), - S.addClause(lits); - } -} - -// Inserts problem into solver. Returns FALSE upon immediate conflict. -// -static void parse_DIMACS(FILE* fptr, Solver& S) { - int size; - char* text = readFile(fptr, &size); - StringBuffer in(text, size); - parse_DIMACS_main(in, S); - free(text); } - -// Faster and more memory efficient parsing from a file. -// -static void parse_DIMACS(cchar* input_file, Solver& S) { - FileBuffer in(input_file); - parse_DIMACS_main(in, S); } - - -//================================================================================================= -// Main - - -static void SIGINT_signalHandler(int signum) { - printf("\n*** INTERRUPTED ***\n"); exit(-1); } - - -void printStats(SolverStats& stats, double cpu_time) -{ - reportf("starts : %8"I64_fmt"\n", stats.starts); - reportf("conflicts : %8"I64_fmt" (%.0f /sec)\n", stats.conflicts , stats.conflicts /cpu_time); - reportf("reduce learnts : %8"I64_fmt" (%.0f /sec)\n", stats.reduceDBs , stats.reduceDBs /cpu_time); - reportf("decisions : %8"I64_fmt" (%.0f /sec)\n", stats.decisions , stats.decisions /cpu_time); - reportf("propagations : %8"I64_fmt" (%.0f /sec)\n", stats.propagations, stats.propagations/cpu_time); - reportf("inspects : %8"I64_fmt" (%.0f /sec)\n", stats.inspects , stats.inspects /cpu_time); - reportf("memory used : %8g MB\n", memUsed() / (1024*1024.0)); - reportf("CPU time : %8g s\n", cpu_time); - if (tsum() != 0.0) - reportf("Profile time : %8g seconds\n", tsum()); -} - - -int main(int argc, char** argv) -{ - signal(SIGINT, SIGINT_signalHandler); // (handle Control-C) - signal(SIGHUP, SIGINT_signalHandler); - - parseOptions(argc, argv); - Solver S(occ_Off, (opt_ext_sat) ? NULL :elimed_file); - bool st; - - if (!opt_ext_sat){ - // STANDARD MODE: - // - reportf("Parsing...\n"); - if (input_file == NULL) - parse_DIMACS(stdin, S); - else{ - cchar* name = input_file; - int len = strlen(name); - - if (strcmp(name+len-5, ".bcnf") == 0){ - parse_BCNF(name, S); - - }else{ - char* tmp = NULL; - int stat = 0; - if (len >= 3 && strcmp(name+len-3, ".gz") == 0){ - tmp = xstrdup("/tmp/tmp_CNF__XXXXXX"); - int fd = mkstemp(tmp); - if (fd == -1) - fprintf(stderr, "ERROR! Could not create temporary file for unpacking problem.\n"), - exit(1); - else - close(fd); - stat = system(sFree(nsprintf("zcat %s > %s", name, tmp))); - if (stat != 0) fprintf(stderr, "ERROR! Could not open file: %s\n", name), exit(1); - parse_DIMACS(tmp, S); - }else - parse_DIMACS(name, S); - if (tmp != NULL) - remove(tmp); - } - } - S.setOccurMode(occ_Permanent); - - S.verbosity = verbosity; - st = S.solve(); - printStats(S.stats, cpuTime()); - reportf("\n"); - #ifdef SAT_LIVE - printf(st ? "s SATISFIABLE\n" : "s UNSATISFIABLE\n"); - #else - reportf(st ? "SATISFIABLE\n" : "UNSATISFIABLE\n"); - #endif - - }else{ - // EXTEND A MODEL FROM MINISAT: [HACK!] - // - if (output_file == NULL) fprintf(stderr, "ERROR! Result file from external SAT solver missing when using '+ext'.\n"), exit(1); - if (varmap_file == NULL) fprintf(stderr, "ERROR! VarMap file from external SAT solver missing when using '+ext'.\n"), exit(1); - if (elimed_file == NULL) fprintf(stderr, "ERROR! Elimed file from external SAT solver missing when using '+ext'.\n"), exit(1); - - // Open result file: - int result_size; - cchar* result = readFile(output_file, &result_size); - if (result_size == 6 && strcmp(result, "UNSAT\n") == 0){ - printf("s UNSATISFIABLE\n"); - exit(20); - }else if (result_size < 4 || strncmp(result, "SAT\n", 4) != 0) - fprintf(stderr, "ERROR! Invalid result file from external SAT solver.\n"), exit(1); - - // SATISFIABLE: - - // Read variable map: (including some unit clauses derived during pre-processing) - int varmap_size; - cchar* varmap = readFile(varmap_file, &varmap_size); - vec vmap; - int n_vars, val; - StringBuffer map(varmap, varmap_size); - n_vars = parseInt(map); skipLine(map); - while (S.nVars() < n_vars) S.newVar(); - - for(;;){ - val = parseInt(map); - if (val == 0) break; - S.addUnit( (val > 0) ? Lit(val-1) : ~Lit(-val-1) ); } - for(;;){ - val = parseInt(map); - if (val == 0) break; - vmap.push(val-1); } - - // Read model: - StringBuffer res(result + 4, result_size - 4); - bool neg; - Lit p; - for(;;){ - val = parseInt(res); - if (val == 0) break; - if (val < 0) val = -val, neg = true; - else neg = false; - val--; - if (val >= vmap.size()) fprintf(stderr, "ERROR! Too few variables in variable map file: %s\n", varmap_file), exit(1); - p = Lit(vmap[val], neg); - S.addUnit(p); - } - - // Extend model: - FILE* in = fopen(elimed_file, "rb"); if (in == NULL) fprintf(stderr, "ERROR! Could not open file for reading: %s\n", elimed_file), exit(1); - vec io_tmp; - int n, size; - for(;;){ - n = fread(&p, 4, 1, in); - if (n == 0) break; - size = index(p); - - io_tmp.clear(); - io_tmp.growTo(size); - fread((Lit*)io_tmp, 4, size, in); - - S.addClause(io_tmp); /*DEBUG*/if (!S.ok) reportf("PANIC! False clause read back: "), dump(S, io_tmp); - assert(S.ok); - } - fclose(in); - - st = S.solve(); assert(st); - } - - if (st){ - #ifdef SAT_LIVE - FILE* out = stdout; - printf("s SATISFIABLE\n"); - printf("v "); - #else - FILE* out; - if (model_file != NULL) { - out = fopen(model_file, "wb"); - if (out == NULL) fprintf(stderr, "WARNING! Could not write model to: %s\n", model_file); - }else{ -#ifdef VERIFY_MODEL - out = createTmpFile("/tmp/tmp_model__", "wb", (char*)model_file); -#else - out = NULL; -#endif - } -#endif - if (out != NULL){ - for (int i = 0; i < S.model.size(); i++) - if (S.model[i] != l_Undef) - fprintf(out, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1); - } - fprintf(out, " 0\n"); -#ifndef SAT_LIVE - if (out != NULL) fflush(out); - #endif - -#ifdef VERIFY_MODEL - if (input_file != NULL) - reportf("Verifying model...\n"), - verifyModel(input_file, model_file), - reportf("OK!\n"); -#endif - } - - exit(st ? 10 : 20); // (faster than "return", which will invoke the destructor for 'Solver') - -} diff --git a/sources/SatElite/SatELite/Main.h b/sources/SatElite/SatELite/Main.h deleted file mode 100644 index b6e7aec..0000000 --- a/sources/SatElite/SatELite/Main.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef Main_h -#define Main_h - -//================================================================================================= - - -extern bool opt_confl_1sub ; -extern bool opt_confl_ksub ; -extern bool opt_var_elim ; -extern bool opt_0sub ; -extern bool opt_1sub ; -extern bool opt_2sub ; -extern bool opt_repeated_sub; -extern bool opt_def_elim ; -extern bool opt_unit_def ; -extern bool opt_hyper1_res ; -extern bool opt_pure_literal; -extern bool opt_asym_branch ; -extern bool opt_pre_sat ; -extern bool opt_keep_all ; -extern bool opt_no_random ; - -extern bool opt_niver; -extern cchar* output_file; -extern cchar* varmap_file; -extern int verbosity; - -void verifyModel(cchar* input_file, cchar* model_file); - - -//================================================================================================= -#endif diff --git a/sources/SatElite/SatELite/Main_debug.C b/sources/SatElite/SatELite/Main_debug.C deleted file mode 100644 index 1cbb7dc..0000000 --- a/sources/SatElite/SatELite/Main_debug.C +++ /dev/null @@ -1,171 +0,0 @@ -#include "Main.h" -#include "Solver.h" -#include - - -//================================================================================================= -// Solver Stub: - - -typedef vec VClause; - -struct VSolver { - vec clauses; - int n_vars; - - VSolver(void) : n_vars(0) {} - ~VSolver(void) { for (int i = 0; i < clauses.size(); i++) delete clauses[i]; } - - VClause* addClause(VClause& c); - int nVars(void) { return n_vars; } - -}; - - -VClause* VSolver::addClause(VClause& c) -{ - for (int i = 0; i < c.size()-1; i++) - if (c[i] == ~c[i+1]) - return NULL; - -// VClause* tmp = new VClause(c.size()); - VClause* tmp = new VClause(xmalloc(c.size()), c.size()); // (allocate block of right size to save memory) - for (int i = 0; i < c.size(); i++) - (*tmp)[i] = c[i]; - for (int i = 0; i < c.size(); i++) - n_vars = max(n_vars, var(c[i]) + 1); - clauses.push(tmp); - return tmp; -} - - -//================================================================================================= -// DIMACS Parser: - - -static void skipWhitespace(char*& in) { - while ((*in >= 9 && *in <= 13) || *in == 32) - in++; } - -static void skipLine(char*& in) { - for (;;){ - if (*in == 0) return; - if (*in == '\n') { in++; return; } - in++; } } - -static int parseInt(char*& 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(1); - while (*in >= '0' && *in <= '9') - val = val*10 + (*in - '0'), - in++; - return neg ? -val : val; } - -static void readClause(char*& in, VSolver& S, vec& lits) { - int parsed_lit, var; - lits.clear(); - for (;;){ - parsed_lit = parseInt(in); - if (parsed_lit == 0) break; - var = abs(parsed_lit)-1; - lits.push( (parsed_lit > 0) ? Lit(var) : ~Lit(var) ); - } -} - - -static void parse_DIMACS_main(char* in, VSolver& S) { - vec lits; - for (;;){ - skipWhitespace(in); - if (*in == 0) - break; - else if (*in == 'c' || *in == 'p') - skipLine(in); - else{ - readClause(in, S, lits); - S.addClause(lits); - } - } -} - - -static void parse_DIMACS(FILE* in, VSolver& S) { - char* text = readFile(in); - parse_DIMACS_main(text, S); - free(text); } - - -//================================================================================================= -// Verify model: - - -void verifyModel(cchar* name, cchar* model) -{ - // Parse CNF: - VSolver S; - int len = strlen(name); - char* tmp = NULL; - int stat = 0; - FILE* in; - if (len > 5 && strcmp(name+len-5, ".bcnf") == 0){ - reportf("(cannot verify BCNF files)\n"); return; } - if (len > 3 && strcmp(name+len-3, ".gz") == 0){ - tmp = xstrdup("tmp_XXXXXX"); - int fd = mkstemp(tmp); - if (fd == -1) - fprintf(stderr, "ERROR! Could not create temporary file for unpacking problem.\n"), - exit(1); - else - close(fd); - stat = system(sFree(nsprintf("zcat %s > %s", name, tmp))); - in = fopen(tmp, "rb"); - }else - in = fopen(name, "rb"); - if (stat != 0 || in == NULL) - fprintf(stderr, "ERROR! Could not open file: %s\n", name), - exit(1); - parse_DIMACS(in, S); - fclose(in); - if (tmp != NULL) - remove(tmp); - - // Parse model: - vec true_lits(S.nVars()*2, false); - int lit; - in = fopen(model, "rb"); assert(in != NULL); - for(;;){ - int n = fscanf(in, "%d", &lit); - if (n != 1 || lit == 0) break; - if (lit < 0) - true_lits[index(~Lit(-lit-1))] = true; - else - true_lits[index( Lit( lit-1))] = true; - } - fclose(in); - - //for (int i = 0; i < true_lits.size(); i++) - // if (true_lits[i]) printf(L_LIT" ", L_lit(toLit(i))); - //printf("\n"); - - // Check satisfaction: - for (int i = 0; i < S.clauses.size(); i++){ - VClause& c = *S.clauses[i]; - for (int j = 0; j < c.size(); j++){ - if (true_lits[index(c[j])]) - goto Satisfied; - } - - printf("FALSE MODEL!!!\n"); - printf("{"); - for (int j = 0; j < c.size(); j++) - printf(" x%d:%d", var(c[j]), true_lits[index(c[j])]); - printf(" }\n"); - exit(0); - - Satisfied:; - } -} diff --git a/sources/SatElite/SatELite/Makefile b/sources/SatElite/SatELite/Makefile deleted file mode 100644 index 6a99e88..0000000 --- a/sources/SatElite/SatELite/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -include $(FM)/options.mak -INCLUDES := $(INCLUDES) --include Profile.h -include $(FM)/template.mak diff --git a/sources/SatElite/SatELite/Profile.C b/sources/SatElite/SatELite/Profile.C deleted file mode 100644 index ec9665c..0000000 --- a/sources/SatElite/SatELite/Profile.C +++ /dev/null @@ -1,3 +0,0 @@ -uint64 t_total__ = 0; -uint64 t_mark__ = 0; -int t_reclev__ = 0; diff --git a/sources/SatElite/SatELite/Profile.h b/sources/SatElite/SatELite/Profile.h deleted file mode 100644 index 9966fdb..0000000 --- a/sources/SatElite/SatELite/Profile.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef Profile_h -#define Profile_h - -//================================================================================================= - - -extern __inline__ uint64 rdtsc(void) { - uint64 x; - __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); - return x; } - -extern uint64 t_total__; -extern uint64 t_mark__; -extern int t_reclev__; - -macro void tset(void) { if (t_reclev__ == 0) t_mark__ = rdtsc(); t_reclev__++; } -macro void tclr(void) { t_reclev__--; if (t_reclev__ == 0) t_total__ += rdtsc() - t_mark__; } -macro double tsum(void) { return (double)t_total__ / 2050000000.0; } // (approximation of the CPU frequency goes here...) - -struct TimeIt_t { - TimeIt_t(void) { tset(); } - ~TimeIt_t(void) { tclr(); } -}; - -#define TimeIt TimeIt_t TimeIt_dummy; - - -//================================================================================================= -#endif diff --git a/sources/SatElite/SatELite/Queue.h b/sources/SatElite/SatELite/Queue.h deleted file mode 100644 index ca7d890..0000000 --- a/sources/SatElite/SatELite/Queue.h +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************************** - -Queue.h -- (C) Niklas Een, 2003 - -Simple implementation of a queue (intended to queue propagations). - -**************************************************************************************************/ - -#ifndef Queue_h -#define Queue_h - - -//================================================================================================= - - -template -class Queue { - vec elems; - int first; - -public: - Queue(void) : first(0) { } - - void insert(T x) { elems.push(x); } - T dequeue(void) { return elems[first++]; } - void clear(void) { elems.clear(); first = 0; } - int size(void) { return elems.size() - first; } - - bool has(T x) { for (int i = first; i < elems.size(); i++) if (elems[i] == x) return true; return false; } -}; - - -//================================================================================================= -#endif diff --git a/sources/SatElite/SatELite/Solver.C b/sources/SatElite/SatELite/Solver.C deleted file mode 100644 index 12c09f6..0000000 --- a/sources/SatElite/SatELite/Solver.C +++ /dev/null @@ -1,997 +0,0 @@ -/************************************************************************************************** - -Solver.C -- (C) Niklas Een, Niklas Sörensson, 2004 - -A simple Chaff-like SAT-solver with support for incremental SAT. - -**************************************************************************************************/ - -#include "Solver.h" -#include "Main.h" -#include "Sort.h" -#include - -#include "Solver_clause.iC" // (purely for efficiency reasons!) - - -//================================================================================================= -// Minor methods: - - -// Creates a new SAT variable in the solver. If 'decision_var' is cleared, variable will not be -// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result). -// -Var Solver::newVar(void) -{ - int index; - index = nVars(); - watches .push(); // (list for positive literal) - watches .push(); // (list for negative literal) - occur .push(); - occur .push(); - n_occurs .push(0); - n_occurs .push(0); - reason .push(Clause_NULL); - assigns .push(toInt(l_Undef)); - level .push(-1); - activity .push(0); - #ifdef VAR_ORDER_2 - lt_activity .push(0); - #endif - order .newVar(); - seen_tmp .push(0); // (one for each polarity) - seen_tmp .push(0); - touched .push(1); - touched_list.push(index); - touched_tmp .push(0); - var_elimed .push(0); - frozen .push(0); - return index; -} - - -// Can only be used if no variables have been created (no previous calls to 'newVar()' or 'setVars()'). -// -void Solver::setVars(int n_vars) -{ - // Hmm, doesn't work very well... Debug later - assert(nVars() == 0); - watches .growTo(2*n_vars); - occur .growTo(2*n_vars); - n_occurs .growTo(2*n_vars, 0); - reason .growTo(n_vars , Clause_NULL); - assigns .growTo(n_vars , toInt(l_Undef)); - level .growTo(n_vars , -1); - activity .growTo(n_vars, 0); - #ifdef VAR_ORDER_2 - lt_activity .growTo(n_vars, 0); - #endif - seen_tmp .growTo(2*n_vars, 0); - touched .growTo(n_vars, 1); - touched_list.growTo(n_vars); for (int i = 0; i < n_vars; i++) touched_list[i] = i; - touched_tmp .growTo(n_vars, 0); - var_elimed .growTo(n_vars, 0); - frozen .growTo(n_vars, 0); - - for (int i = 0; i < n_vars; i++) - order.newVar(); -} - - -// Returns FALSE if immediate conflict. -bool Solver::assume(Lit p) { - assert(propQ.size() == 0); - if (verbosity >= 2) reportf(L_IND"assume("L_LIT")\n", L_ind, L_lit(p)); - trail_lim.push(trail.size()); - return enqueue(p); } - - -// Revert one variable binding on the trail. -// -inline void Solver::undoOne(void) -{ - if (verbosity >= 2){ Lit p = trail.last(); reportf(L_IND"unbind("L_LIT")\n", L_ind, L_lit(p)); } - Lit p = trail.last(); trail.pop(); - Var x = var(p); - assigns[x] = toInt(l_Undef); - reason [x] = Clause_NULL; - level [x] = -1; - order.undo(x); -} - - -// Reverts to the state before last 'assume()'. -// -void Solver::cancel(void) -{ - assert(propQ.size() == 0); - if (verbosity >= 2){ if (trail.size() != trail_lim.last()){ Lit p = trail[trail_lim.last()]; reportf(L_IND"cancel("L_LIT")\n", L_ind, L_lit(p)); } } - for (int c = trail.size() - trail_lim.last(); c != 0; c--) - undoOne(); - trail_lim.pop(); -} - - -// Revert to the state at given level. -// -void Solver::cancelUntil(int level) { - while (decisionLevel() > level) cancel(); } - - -// Record a clause and drive backtracking. 'clause[0]' must contain the asserting literal. -// -void Solver::record(const vec& clause) -{ - assert(clause.size() != 0); - Clause c = addClause(clause, true); assert(ok); - check(enqueue(clause[0], c)); -} - - -//================================================================================================= -// Major methods: - - -Solver::~Solver(void) -{ - assert(iter_vecs.size() == 0); assert(iter_sets.size() == 0); - for (int i = 0; i < constrs.size(); i++) if (!constrs[i].null()) deallocClause(constrs[i], true); - for (int i = 0; i < learnts.size(); i++) if (!learnts[i].null()) deallocClause(learnts[i], true); - deleteTmpFiles(); -} - - -/*_________________________________________________________________________________________________ -| -| analyze : (confl : Clause) (out_learnt : vec&) (out_btlevel : int&) -> [void] -| -| Description: -| Analyze conflict and produce a reason clause. -| -| Pre-conditions: -| * 'out_learnt' is assumed to be cleared. -| * Current decision level must be greater than root level. -| -| Post-conditions: -| * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. -| -| Effect: -| Will undo part of the trail, upto but not beyond the assumption of the current decision level. -|________________________________________________________________________________________________@*/ -void Solver::analyze(Clause confl, vec& out_learnt, int& out_btlevel) -{ - vec& seen = seen_tmp; - int pathC = 0; - Lit p = lit_Undef; - vec p_reason; - - // Generate conflict clause: - // -#if 1 -// Niklas Sörensson's version - // Generate conflict clause: - // - out_learnt.push(); // (leave room for the asserting literal) - out_btlevel = 0; - int index = trail.size()-1; - do{ - assert(confl != Clause_NULL); // (otherwise should be UIP) - if (confl.learnt()) claBumpActivity(confl); - - for (int j = p == lit_Undef ? 0 : 1; j < confl.size(); j++){ - Lit q = confl(j); - if (!seen[var(q)] && level[var(q)] > 0){ - seen[var(q)] = 1; - varBumpActivity(q); - if (level[var(q)] == decisionLevel()) - pathC++; - else{ - out_learnt.push(q), - out_btlevel = max(out_btlevel, level[var(q)]); - } - } - } - - // Select next clause to look at: - while (!seen[var(trail[index--])]); - p = trail[index+1]; - confl = reason[var(p)]; - seen[var(p)] = 0; - pathC--; - - }while (pathC > 0); - out_learnt[0] = ~p; - -#else - out_learnt.push(); // (leave room for the asserting literal) - out_btlevel = 0; - do{ - assert(!confl.null()); // (otherwise should be UIP) - - p_reason.clear(); - calcReason(confl, p, p_reason); - - for (int j = 0; j < p_reason.size(); j++){ - Lit q = p_reason[j]; - if (!seen[var(q)] && level[var(q)] > 0){ - #ifdef BUMP_MORE - varBumpActivity(q); - #endif - seen[var(q)] = 1; - if (level[var(q)] == decisionLevel()) - pathC++; - else{ - out_learnt.push(~q), - out_btlevel = max(out_btlevel, level[var(q)]); - } - } - } - - // Select next clause to look at: - do{ - p = trail.last(); - confl = reason[var(p)]; - undoOne(); - }while (!seen[var(p)]); - pathC--; - seen[var(p)] = 0; - }while (pathC > 0); - out_learnt[0] = ~p; -#endif - - #ifndef BUMP_MORE - // Bump variables: - for (int i = 0; i < out_learnt.size(); i++) - varBumpActivity(out_learnt[i]); - #endif - - // Remove literals: -//#define DEBUG_CSK - #ifdef DEBUG_CSK - vec seen_copy; seen.copyTo(seen_copy); - vec out_learnt_copy; out_learnt.copyTo(out_learnt_copy); - vec candidate; - #endif - - vec to_clear(out_learnt.size()); for (int i = 0; i < out_learnt.size(); i++) to_clear[i] = var(out_learnt[i]); - if (opt_confl_ksub){ - vec levels; - for (int i = 1; i < out_learnt.size(); i++) - levels.push(level[var(out_learnt[i])]); - sortUnique(levels); - - for (int k = 0; k < levels.size(); k++){ - assert(levels[k] > 0); - int from = trail_lim[levels[k]-1]; - int to = (levels[k] >= trail_lim.size()) ? trail.size() : trail_lim[levels[k]]; - for (int i = from; i < to; i++){ - Var x = var(trail[i]); - Clause r = reason[x]; - if (!r.null()){ - for (int j = 1; j < r.size(); j++) - if (seen[var(r[j])] == 0 && level[var(r[j])] != 0) - goto NoConsequence; - seen[x] = 2; - to_clear.push(x); - NoConsequence:; - } - } - } - for (int i = 0; i < out_learnt.size(); i++) - if (seen[var(out_learnt[i])] == 2) - out_learnt[i] = lit_Undef; - - #ifdef DEBUG_CSK - for (int i = 0; i < out_learnt.size(); i++) - if (out_learnt[i] != lit_Undef) - candidate.push(out_learnt[i]); - seen_copy.copyTo(seen); - out_learnt_copy.copyTo(out_learnt); - - for (int i = 0; i < out_learnt.size(); i++){ - Clause c = reason[var(out_learnt[i])]; - if (!c.null()){ - assert(c[0] == ~out_learnt[i]); - for (int j = 1; j < c.size(); j++){ - if (seen[var(c[j])] != 1) - goto Done2; - } - out_learnt[i] = lit_Undef; - Done2:; - } - } - #endif - - }else if (opt_confl_1sub){ - for (int i = 0; i < out_learnt.size(); i++){ - Clause c = reason[var(out_learnt[i])]; - if (!c.null()){ - assert(c[0] == ~out_learnt[i]); - for (int j = 1; j < c.size(); j++){ - if (seen[var(c[j])] != 1) - goto Done; - } - out_learnt[i] = lit_Undef; - Done:; - } - } - } - if (opt_confl_1sub || opt_confl_ksub){ - int new_sz = 0; - for (int i = 0; i < out_learnt.size(); i++) - if (out_learnt[i] != lit_Undef) - out_learnt[new_sz++] = out_learnt[i]; - out_learnt.shrink(out_learnt.size() - new_sz); - } - #ifdef DEBUG_CSK - if (candidate.size() > out_learnt.size()){ - reportf("csk: "), dump(candidate); - reportf("cs1: "), dump(out_learnt); - exit(0); - } - #endif - - - // Clear 'seen': - for (int j = 0; j < to_clear.size(); j++) seen[to_clear[j]] = 0; // ('seen[]' is now cleared) - - if (verbosity >= 2){ - reportf(L_IND"Learnt {", L_ind); - for (int i = 0; i < out_learnt.size(); i++) reportf(" "L_LIT, L_lit(out_learnt[i])); - reportf(" } at level %d\n", out_btlevel); } -} - - -/*_________________________________________________________________________________________________ -| -| enqueue : (p : Lit) (from : Clause) -> [bool] -| -| Description: -| Puts a new fact on the propagation queue as well as immediately updating the variable's value. -| Should a conflict arise, FALSE is returned. -| -| Input: -| p - The fact to enqueue -| from - [Optional] Fact propagated from this (currently) unit clause. Stored in 'reason[]'. -| Default value is NULL (no reason). -| -| Output: -| TRUE if fact was enqueued without conflict, FALSE otherwise. -|________________________________________________________________________________________________@*/ -bool Solver::enqueue(Lit p, Clause from) -{ - if (value(p) != l_Undef){ - #ifdef RELEASE - return value(p) != l_False; - #else - if (value(p) == l_False){ - // Conflicting enqueued assignment - assert(decisionLevel() > 0); - return false; - }else if (value(p) == l_True){ - // Existing consistent assignment -- don't enqueue - return true; - }else{ - assert(value(p) == l_Error); - // Do nothing -- clause should be removed. - return true; - } - #endif - }else{ - // New fact -- store it. - #ifndef RELEASE - if (verbosity >= 2) reportf(L_IND"bind("L_LIT")\n", L_ind, L_lit(p)); - #endif - assigns[var(p)] = toInt(lbool(!sign(p))); - level [var(p)] = decisionLevel(); - reason [var(p)] = from; - trail.push(p); - propQ.insert(p); - return true; - } -} - - -/*_________________________________________________________________________________________________ -| -| propagateToplevel : [void] -> [void] -| -| Description: -| Destructively update clause database with enqueued top-level facts. -|________________________________________________________________________________________________@*/ -void Solver::propagateToplevel(void) -{ - assert(decisionLevel() == 0); - - for (int i = 0; i < units.size(); i++){ - if (!enqueue(units[i])){ - propQ.clear(); - return; } } - units.clear(); - - while (propQ.size() > 0){ - Lit p = propQ.dequeue(); - vec cs; - - // Remove satisfied clauses: - occur[index(p)].moveTo(cs); - for (int i = 0; i < cs.size(); i++) - removeClause(cs[i]); - - // Remove false literals from clauses: - occur[index(~p)].moveTo(cs); - registerIteration(cs); - for (int i = 0; i < cs.size(); i++){ - if (!cs[i].null()) - strengthenClause(cs[i], ~p); // (may enqueue new facts to propagate) - } - unregisterIteration(cs); - } - propQ.clear(); -} - - -/*_________________________________________________________________________________________________ -| -| propagate : [void] -> [Clause] -| -| Description: -| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned, -| otherwise NULL. -| -| Post-conditions: -| * the propagation queue is empty, even if there was a conflict. -|________________________________________________________________________________________________@*/ -#if 0 -// Standard -Clause Solver::propagate(void) -{ - if (decisionLevel() == 0 && occur_mode != occ_Off){ - propagateToplevel(); - return Clause_NULL; - } - - Clause confl; - while (propQ.size() > 0){ - stats.propagations++; - Lit p = propQ.dequeue(); // 'p' is enqueued fact to propagate. - vec& ws = watches[index(p)]; - bool keep_watch; - int i, j; - for (i = j = 0; confl.null() && i < ws.size(); i++){ - stats.inspects++; - keep_watch = false; - if (!propagateClause(ws[i], p, keep_watch)) - confl = ws[i], - propQ.clear(); - if (keep_watch) - ws[j++] = ws[i]; - } - - // Copy the remaining watches: - while (i < ws.size()) - ws[j++] = ws[i++]; - - watches[index(p)].shrink(i - j); - } - - return confl; -} -#endif - -#if 0 -// Optimized -Clause Solver::propagate(void) -{ - if (decisionLevel() == 0 && occur_mode != occ_Off){ - propagateToplevel(); - return Clause_NULL; - } - - Clause confl; - while (propQ.size() > 0){ - stats.propagations++; - Lit p = propQ.dequeue(); // 'p' is enqueued fact to propagate. - vec& ws = watches[index(p)]; - int i, j; - for (i = j = 0; i < ws.size(); i++){ - stats.inspects++; - - // Make sure the false literal is c[1]: - Clause& c = ws[i]; - Lit false_lit = ~p; - if (c(0) == false_lit) - c(0) = c(1), c(1) = false_lit; - assert(c(1) == false_lit); - - // If 0th watch is true, then clause is already satisfied. - if (value(c(0)) == l_True){ - ws[j++] = ws[i]; - goto Continue; } - - // Look for new watch: - for (int k = 2; k < c.size(); k++){ - if (value(c(k)) != l_False){ - c(1) = c(k), c(k) = false_lit; - watches[index(~c(1))].push(c); - goto Continue; } } - - // Clause is unit under assignment: - ws[j++] = ws[i]; - if (!enqueue(c(0), c)){ - confl = ws[i], - propQ.clear(); - i++; break; - } - - Continue:; - } - - // Copy the remaining watches: - while (i < ws.size()) - ws[j++] = ws[i++]; - - watches[index(p)].shrink(i - j); - } - - return confl; -} -#endif - -#if 1 -// Borrowed from Niklas Sörensson -- uses "unsafe" type casts to achieve maximum performance -Clause Solver::propagate(void) -{ - if (decisionLevel() == 0 && occur_mode != occ_Off){ - propagateToplevel(); - return Clause_NULL; - } - assert(watches_setup); - - Clause confl = Clause_NULL; - while (propQ.size() > 0){ - stats.propagations++; - Lit p = propQ.dequeue(); // 'p' is enqueued fact to propagate. - vec& ws = watches[index(p)]; - Clause_t **i, **j, **end = (Clause_t**)(Clause*)ws + ws.size(); - for (i = j = (Clause_t**)(Clause*)ws; confl == NULL && i < end; ){ - stats.inspects++; - Clause_t& c = **i; - - // Make sure the false literal is data[1]: - Lit false_lit = ~p; - if (c(0) == false_lit) - c(0) = c(1), c(1) = false_lit; - - assert(c(1) == false_lit); - - // If 0th watch is true, then clause is already satisfied. - if (value(c(0)) == l_True) - *j++ = *i; - else{ - // Look for new watch: - for (int k = 2; k < c.size(); k++) - if (value(c(k)) != l_False){ - c(1) = c(k); c(k) = false_lit; - watches[index(~c(1))].push(&c); - goto next; } - - // Clause is unit under assignment: - *j++ = *i; - if (!enqueue(c(0), &c)){ - confl = *(Clause*)i; - propQ.clear(); - } - } - next: - i++; - } - - // Copy the remaining watches: - while (i < end) - *j++ = *i++; - - ws.shrink(i - j); - } - - return confl; -} -#endif - - -/*_________________________________________________________________________________________________ -| -| reduceDB : () -> [void] -| -| Description: -| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked -| clauses are clauses that are reason to a some assignment. -|________________________________________________________________________________________________@*/ -bool satisfied(Solver& S, Clause c) -{ - for (int i = 0; i < c.size(); i++){ - if ((S.value(c[i]) == l_True && S.level[var(c[i])] == 0) || S.value(c[i]) == l_Error) // (l_Error means variable is eliminated) - return true; } - return false; -} - -struct reduceDB_lt { bool operator () (Clause x, Clause y) { return x.activity() < y.activity(); } }; -void Solver::reduceDB(void) -{ -/**/if (occur_mode == occ_All) return; // <<= Temporary fix - - // <<= BAD IMPLEMENTATION! FIX! - stats.reduceDBs++; - int i; - double extra_lim = cla_inc / learnts.size(); // Remove any clause below this activity - vec ls; - for (int i = 0; i < learnts.size(); i++) - if (!learnts[i].null()) - ls.push(learnts[i]); - - sort(ls, - reduceDB_lt()); - for (i = 0; i < ls.size() / 3; i++){ - if (!locked(ls[i])) - removeClause(ls[i]); - } - for (; i < ls.size(); i++){ -// if (!locked(ls[i]) && ls[i].activity() < extra_lim) - if (!locked(ls[i]) && (ls[i].activity() < extra_lim || satisfied(*this, ls[i]))) - removeClause(ls[i]); - } -} - - -void Solver::compressDB(void) -{ - // UNFINISHED - vec > n_occurs(2*nVars()); - - for (int i = 0; i < n_occurs.size(); i++) - n_occurs[i].fst = 0, - n_occurs[i].snd = i; - - for (int i = 0; i < learnts.size(); i++){ - Clause c = learnts[i]; - if (c == Clause_NULL) goto Skip; - for (int j = 0; j < c.size(); j++) - if (value(c[j]) == l_Error) goto Skip; - - for (int j = 0; j < c.size(); j++) - n_occurs[index(c[j])].fst--; - Skip:; - } - - sort(n_occurs); - - /**/for (int i = 0; i < n_occurs.size(); i++) if (n_occurs[i].fst != 0) reportf("%d ", n_occurs[i].fst); reportf("\n"); exit(0); -} - - -/*_________________________________________________________________________________________________ -| -| simplifyDB : [void] -> [bool] -| -| Description: -| Simplify all constraints according to the current top-level assigment (redundant constraints -| may be removed altogether). -|________________________________________________________________________________________________@*/ -void Solver::simplifyDB(bool subsume) -{ - if (!ok) return; // GUARD (public method) - assert(decisionLevel() == 0); - - // temporary placement -- put at end of solve? <<= flytta till 'propagateToplevel()' - // end - - if (!propagate().null()){ // (cannot use 'propagateToplevel()' here since it behaves different for 'occur_mode == occ_Off') - assert(ok == false); - return; } - - //**/if (occur_mode != occ_Off) clauseReduction(); - - if (nAssigns() == last_simplify) - return; - last_simplify = nAssigns(); - - // Subsumption simplification: - //*HACK!*/if (!subsume && opt_var_elim){ opt_var_elim = false; if (opt_repeated_sub) reportf(" (var.elim. off)\r"); } - if (occur_mode != occ_Off){ - if (!opt_repeated_sub){ - if (subsume) simplifyBySubsumption(); - }else - simplifyBySubsumption(); - } - - // Removed satisfied clauses from the learnt clause database: - if (stats.inspects - last_inspects > nLearnts() * 32){ - last_inspects = stats.inspects; - for (int i = 0; i < learnts.size(); i++) if (!learnts[i].null() && satisfied(*this, learnts[i])) removeClause(learnts[i]); - } - - //**/if (occur_mode != occ_Off) clauseReduction(); -} - - -/*_________________________________________________________________________________________________ -| -| search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&) -> [lbool] -| -| Description: -| Search for a model the specified number of conflicts, keeping the number of learnt clauses -| below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to -| indicate infinity. -| -| Output: -| 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If -| all variables are decision variables, this means that the clause set is satisfiable. 'l_False' -| if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. -|________________________________________________________________________________________________@*/ -lbool Solver::search(int nof_conflicts, int nof_learnts, const SearchParams& params) -{ - if (!ok) return l_False; // GUARD (public method) - assert(root_level == decisionLevel()); - - stats.starts++; - int conflictC = 0; - var_decay = 1 / params.var_decay; - cla_decay = 1 / params.clause_decay; - model.clear(); - - for (;;){ - Clause confl = propagate(); - if (!confl.null()){ - // CONFLICT - - if (verbosity >= 2) reportf(L_IND"**CONFLICT**\n", L_ind); - stats.conflicts++; conflictC++; - vec learnt_clause; - int backtrack_level; - if (decisionLevel() == root_level) - return l_False; - analyze(confl, learnt_clause, backtrack_level); - cancelUntil(max(backtrack_level, root_level)); - record(learnt_clause); - varDecayActivity(); claDecayActivity(); - - }else{ - // NO CONFLICT - - if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ - // Reached bound on number of conflicts: - progress_estimate = progressEstimate(); - propQ.clear(); - cancelUntil(root_level); - return l_Undef; } - - if (decisionLevel() == 0 && params.simplify){ - // Simplify the set of problem clauses: - simplifyDB(); - if (!ok) return l_False; - } - - if (nof_learnts >= 0 && nLearnts()-nAssigns() >= nof_learnts) - // Reduce the set of learnt clauses: - reduceDB(); - - // New variable decision: - stats.decisions++; - Var next = order.select(params.random_var_freq); - - if (next == var_Undef){ - // Model found: - model.growTo(nVars()); - if (occur_mode == occ_Off) - for (int i = 0; i < nVars(); i++) model[i] = value(i); - else{ - #ifdef WATCH_OPTIMIZATION - watches.clear(true); watches_setup = false; - #endif - extendModel(); - } - cancelUntil(root_level); - return l_True; - } - - check(assume(~Lit(next))); - } - } -} - - -/*_________________________________________________________________________________________________ -| -| extendModel : [void] -> [void] -| -| Description: -| Extend the partial model of the current SAT environment to a full model, reading back -| eliminated clauses from the temporary file. -|________________________________________________________________________________________________@*/ -void Solver::extendModel(void) -{ - if (verbosity >= 1){ - reportf("==============================================================================\n"); - reportf("Extending model [cpu-time: %g s]\n", cpuTime()); } - - //**/int64 mem0 = memUsed(); - #if 1 - // READING FILE FORWARDS (simple) - Solver S(occ_Off); - for (int i = 0; i < nVars(); i++){ - S.newVar(); - if (!var_elimed[i] && value(i) != l_Undef) - S.addUnit(((value(i) == l_True) ? Lit(i) : ~Lit(i))); - } - - fflush(elim_out); - rewind(elim_out); - for(;;){ - Lit p; - int n = fread(&p, 4, 1, elim_out); - if (n == 0) - break; - int size = index(p); - - io_tmp.clear(); - io_tmp.growTo(size); - fread((Lit*)io_tmp, 4, size, elim_out); - - S.addClause(io_tmp); - /**/if (!S.ok) reportf("PANIC! False clause read back: "), dump(S, io_tmp); - assert(S.ok); - } - fflush(elim_out); - - check(S.solve()); - S.model.moveTo(model); - - #else - // READING FILE BACKWARDS - Solver S(occ_Off); - S.setupWatches(); - for (int i = 0; i < nVars(); i++){ - S.newVar(); - if (!var_elimed[i] && value(i) != l_Undef) - S.addUnit(((value(i) == l_True) ? Lit(i) : ~Lit(i))); - } - check(S.propagate() == Clause_NULL); - - fflush(elim_out); - const int chunk_size = 1000; - vec offsets; - vec > tmps(chunk_size); - Lit p; - int n, size, c; - - rewind(elim_out); - offsets.push(ftell(elim_out)); - c = 0; - for(;;){ - n = fread(&p, 4, 1, elim_out); if (n == 0) break; size = index(p); // (read size of clause or abort if no more clauses) - io_tmp.clear(); io_tmp.growTo(size); fread((Lit*)io_tmp, 4, size, elim_out); // (read clause) - c++; - if (c == chunk_size) - offsets.push(ftell(elim_out)), - c = 0; - } - - assert(S.constrs.size() == 0); - assert(S.propQ.size() == 0); - rewind(elim_out); - for (int i = offsets.size() - 1; i >= 0; i--){ - fseek(elim_out, SEEK_SET, offsets[i]); - for(c = 0; c < chunk_size; c++){ - n = fread(&p, 4, 1, elim_out); if (n == 0) break; size = index(p); // (read size of clause or abort if no more clauses) - tmps[c].clear(); tmps[c].growTo(size); fread((Lit*)tmps[c], 4, size, elim_out); // (read clause) - } - for (; c > 0; c--){ - assert(S.watches_setup); - S.addClause(tmps[c-1]); /*DEBUG*/if (!S.ok) reportf("PANIC! False clause read back: "), dump(S, io_tmp); assert(S.ok); - check(S.propagate() == Clause_NULL); - } - } - fseek(elim_out, SEEK_END, 0); - fflush(elim_out); - - check(S.solve()); - S.model.moveTo(model); - #endif - - //**/reportf("MEM USED for extending model: %g MB\n", (memUsed() - mem0) / (1024*1024.0)); -} - - -// Return search-space coverage. Not extremely reliable. -// -double Solver::progressEstimate(void) -{ - int n_vars = 0; for (int i = 0; i < nVars(); i++) n_vars += !var_elimed[i]; - double progress = 0; - double F = 1.0 / n_vars; - for (int i = 0; i < nVars(); i++) - if (value(i) != l_Undef && !var_elimed[i]) - progress += pow(F, level[i]); - return progress / n_vars; -} - - -// Divide all variable activities by 1e100. -// -void Solver::varRescaleActivity(void) -{ - for (int i = 0; i < nVars(); i++) - activity[i] *= 1e-100; - var_inc *= 1e-100; -} - - -// Divide all constraint activities by 1e100. -// -void Solver::claRescaleActivity(void) -{ - for (int i = 0; i < learnts.size(); i++) - if (!learnts[i].null()) - learnts[i].activity() *= 1e-20; - cla_inc *= 1e-20; -} - - -/*_________________________________________________________________________________________________ -| -| solve : (assumps : const vec&) -> [bool] -| -| Description: -| Top-level solve. If using assumptions (non-empty 'assumps' vector), you must call -| 'simplifyDB()' first to see that no top-level conflict is present (which would put the solver -| in an undefined state). -|________________________________________________________________________________________________@*/ -bool Solver::solve(const vec& assumps) -{ - if (verbosity >= 1){ - reportf("==============================================================================\n"); - reportf("| | ORIGINAL | LEARNT | |\n"); - reportf("| Conflicts | Clauses Literals | Limit Clauses Literals Lit/Cl | Progress |\n"); - reportf("==============================================================================\n"); - // Hack: - double nof_learnts = 0.3; - int learnt_literals = 0; for (int i = 0; i < learnts.size(); i++) if (!learnts[i].null()) learnt_literals += learnts[i].size(); - reportf("| %9d | %7d %8d | %7d %7d %8d %7.1f | %6.3f %% |\n", (int)stats.conflicts, nClauses(), nLiterals(), (int)(nof_learnts*nClauses()), nLearnts(), learnt_literals, learnt_literals / (double)nLearnts(), progress_estimate*100); - } - - if (occur_mode == occ_Off || opt_asym_branch) setupWatches(); - simplifyDB(true); - if (!ok) return false; - setupWatches(); - - SearchParams params(0.95, 0.999, opt_no_random ? 0 : 0.02); - double nof_conflicts = 100; - double nof_learnts = 0.4; //0.3; - lbool status = l_Undef; - - for (int i = 0; i < assumps.size(); i++){ - assert(!var_elimed[var(assumps[i])]); - if (!propagate().null() || !assume(assumps[i]) || !propagate().null()){ - propQ.clear(); - cancelUntil(0); - return false; } - } - root_level = decisionLevel(); - - while (status == l_Undef){ - //if (verbosity >= 1) reportf("RESTART -- conflicts=%d clauses=%d learnts=%d/%d progress=%.4f %%\n", (int)nof_conflicts, constrs.size(), learnts.size(), (int)(nof_learnts*nClauses()), progress_estimate*100); - if (verbosity >= 1){ - int learnt_literals = 0; for (int i = 0; i < learnts.size(); i++) if (!learnts[i].null()) learnt_literals += learnts[i].size(); - reportf("| %9d | %7d %8d | %7d %7d %8d %7.1f | %6.3f %% |\n", (int)stats.conflicts, nClauses(), nLiterals(), (int)(nof_learnts*nClauses()), nLearnts(), learnt_literals, learnt_literals / (double)nLearnts(), progress_estimate*100); - } - status = search((int)nof_conflicts, (int)(nof_learnts*nClauses()), params); - nof_conflicts *= 1.5; - nof_learnts *= 1.1; - //**/if (learnts.size() > 1000) compressDB(); - } - - if (verbosity >= 1) reportf("==============================================================================\n"); - - cancelUntil(0); - return (status == l_True); -} diff --git a/sources/SatElite/SatELite/Solver.h b/sources/SatElite/SatELite/Solver.h deleted file mode 100644 index 68fbc41..0000000 --- a/sources/SatElite/SatELite/Solver.h +++ /dev/null @@ -1,486 +0,0 @@ -/************************************************************************************************** - -Solver.h -- (C) Niklas Een, Niklas Sörensson, 2004 - -A simple Chaff-like SAT-solver with support for incremental SAT. - -**************************************************************************************************/ - -#ifndef Solver_h -#define Solver_h - -#include "SolverTypes.h" -#include "Queue.h" -#include "VarOrder.h" -#include "TmpFiles.h" - -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#ifdef RELEASE -#define SAT_LIVE -#endif -//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#ifdef SAT_LIVE -#define reportf(format, args...) ( ((verbosity >= 1) ? printf("c "), printf(format , ## args) : 0), fflush(stdout) ) -#else -#define reportf(format, args...) ( ((verbosity >= 1) ? fprintf(stdout, format , ## args) : 0), fflush(stdout) ) -#endif - -//#define WATCH_OPTIMIZATION - -#define BUMP_MORE -//#define VAR_ORDER_2 -//#define TOUCH_LESS - - -//================================================================================================= -// Clause: - - -class Solver; - -struct Clause_t { - int id_; // -1 = dynamic clause - union { - struct { - uint64 abst_; - uint size_learnt; - }; - struct { - char _vec[sizeof(vec)]; - }; - }; - Lit data[0]; - - vec& Vec(void) const { return *((vec*)&_vec); } - - // PUBLIC INTERFACE: - // - bool dynamic (void) const { return id_ == -1; } - int size (void) const { return dynamic() ? Vec().size() : size_learnt >> 1;} - Lit& operator [] (int index) { return dynamic() ? Vec()[index] : data[index]; } - const Lit& operator [] (int index) const { return dynamic() ? Vec()[index] : data[index]; } - Lit& operator () (int index) { assert(!dynamic()); return data[index]; } - const Lit& operator () (int index) const { assert(!dynamic()); return data[index]; } - void push (Lit p) { assert(dynamic()); Vec().push(p); } - void clear (void) { assert(dynamic()); Vec().clear(); } - vec& asVec (void) const { assert(dynamic()); return Vec(); } - - // Constructors: - Clause_t(void) { id_ = -1; new (&Vec()) vec(); } - ~Clause_t(void) { assert(dynamic()); Vec().~vec(); } -}; - - -class Clause { - Clause_t* ptr_; -public: - Clause(void) : ptr_(NULL) {} - Clause(Clause_t& c) : ptr_(&c) {} - Clause(Clause_t* c) : ptr_( c) {} - Clause_t* ptr(void) const { return ptr_; } - - bool operator == (Clause other) const { return ptr_ == other.ptr_; } - bool null(void) const { return ptr_ == NULL; } - void zero(void) { ptr_ = NULL; } - - bool dynamic (void) const { return ptr_->dynamic(); } - int size (void) const { return ptr_->size(); } - Lit& operator [] (int index) { return (*ptr_)[index]; } - const Lit& operator [] (int index) const { return (*ptr_)[index]; } - Lit& operator () (int index) { return (*ptr_)(index); } - const Lit& operator () (int index) const { return (*ptr_)(index); } - - // Dynamic: - void push (Lit p) const { return ptr_->push(p); } - void clear (void) const { return ptr_->clear(); } - vec& asVec (void) const { return ptr_->asVec(); } - - // Non-dynamic: - int id (void) const { assert(!dynamic()); return ptr_->id_; } - uint64 abst (void) const { assert(!dynamic()); return ptr_->abst_; } - bool learnt (void) const { assert(!dynamic()); return ptr_->size_learnt & 1; } - float& activity (void) const { assert(learnt()); return *((float*)&ptr_->data[size()]); } // (learnt clauses only) -}; - -const Clause Clause_NULL = Clause(); - -macro bool operator < (Clause c1, Clause c2) { return (intp)c1.ptr() < (intp)c2.ptr(); } -macro uint hash(Clause c) { return (int)c.id(); } - - - -//================================================================================================= -// Clause Subset: - - -class CSet { - vec where; // Map clause ID to position in 'which'. - vec which; // List of clauses (for fast iteration). May contain 'Clause_NULL'. - vec free; // List of positions holding 'Clause_NULL'. - -public: - Clause operator [] (int index) const { return which[index]; } - int size (void) const { return which.size(); } - int nElems (void) const { return which.size() - free.size(); } - - bool add(Clause c) { - assert(!c.null()); - where.growTo(c.id()+1, -1); - if (where[c.id()] != -1) - return true; - if (free.size() > 0){ - where[c.id()] = free.last(); - which[free.last()] = c; - free.pop(); - }else{ - where[c.id()] = which.size(); - which.push(c); - } - return false; - } - - bool exclude(Clause c) { - assert(!c.null()); - if (c.id() >= where.size() || where[c.id()] == -1) - return false; - free.push(where[c.id()]); - which[where[c.id()]] = Clause_NULL; - where[c.id()] = -1; - return true; - } - - void clear(void) { - for (int i = 0; i < which.size(); i++) - if (!which[i].null()) - where[which[i].id()] = -1; - which.clear(); - free .clear(); - } -}; - - - -//================================================================================================= -// Helpers: - - -template -macro void remove(vec& ws, const T& elem) -{ - int j = 0; - for (; ws[j] != elem ; j++) assert(j < ws.size()); - for (; j < ws.size()-1; j++) ws[j] = ws[j+1]; - ws.pop(); -} - -template macro void maybeRemove(vec& ws, const T& elem) { if (ws.size() > 0) remove(ws, elem); } - - -macro int find(Clause c, Lit p) { - for (int i = 0;; i++){ - assert(i < c.size()); - if (c[i] == p) return i; } } - -template -macro int find(const vec& ws, const T& elem) { // 'find' has pre-condition that the element exists in the vector. - for (int i = 0;; i++){ - assert(i < ws.size()); - if (ws[i] == elem) return i; } } - - -//================================================================================================= -// Solver -- the main class: - - -struct SolverStats { - int64 starts, decisions, propagations, inspects, conflicts, reduceDBs; - SolverStats(void) : starts(0), decisions(0), propagations(0), inspects(0), conflicts(0), reduceDBs(0) { } -}; - - -struct SearchParams { - double var_decay, clause_decay, random_var_freq; // (reasonable values are: 0.95, 0.999, 0.02) - bool simplify; - SearchParams(double v = 1, double c = 1, double r = 0, bool s = true) : var_decay(v), clause_decay(c), random_var_freq(r), simplify(s) {} -}; - -enum OccurMode { occ_Off, occ_Permanent, occ_All }; - - -struct Solver { - -// INTERNAL - - bool ok; // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used! - vec constrs; // Set of problem clauses. - vec constrs_free; // Free list for problem clauses. - vec learnts; // Set of learnt clauses. - vec learnts_free; // Free list for learnt clauses. - double cla_inc; // Amount to bump next clause with. - double cla_decay; // INVERSE decay factor for clause activity: stores 1/decay. - int n_literals; // Literal count -- for output mainly. Only includes *problem* clauses. - FILE* elim_out; // File storing eliminated clauses (needed to calculate model). - char* elim_out_file; // (name of file) - vec*> iter_vecs; // Vectors currently used for iterations. Removed clauses will be looked up and replaced by 'Clause_NULL'. - vec iter_sets; // Sets currently used for iterations. - - vec activity; // A heuristic measurement of the activity of a variable. - double var_inc; // Amount to bump next variable with. - double var_decay; // INVERSE decay factor for variable activity: stores 1/decay. Use negative value for static variable order. - #ifdef VAR_ORDER_2 - vec lt_activity; // Long term activity. - VarOrder2 order; // Keeps track of the decision variable order. - #else - VarOrder order; // Keeps track of the decision variable order. - #endif - - vec > watches; // 'watches[index(lit)]' is a list of constraints watching 'lit' (will go there if literal becomes true). - bool watches_setup; // Are the watcher lists set up yet? ('false' initially) - vec > occur; // 'occur[index(lit)]' is a list of constraints containing 'lit'. - OccurMode occur_mode; // What clauses to keep in the occur lists. - vec n_occurs; // Literal occurance count -- only for problem clauses. Used for pure-literal rule. - Queue propQ; // Propagation queue. - - vec assigns; // The current assignments (lbool:s stored as char:s). - vec units; // ... the other solution to 'persistent'; re-propagate when reach toplevel. - vec trail; // List of assignments made. - vec trail_lim; // Separator indices for different decision levels in 'trail'. - vec reason; // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none. - vec level; // 'level[var]' is the decision level at which assignment was made. - int root_level; // Level of first proper decision. - int last_simplify; // Number of top-level assignments at last 'simplifyDB()'. - - vec touched; // Is set to true when a variable is part of a removed clause. Also true initially (upon variable creation). - vec touched_list; // A list of the true elements in 'touched'. - CSet cl_touched; // Clauses strengthened. - CSet cl_added; // Clauses created. - bool fwd_subsump; // Forward subsumption activated? - - vec var_elimed; // 'eliminated[var]' is TRUE if variable has been eliminated. - vec frozen; // Variables currently not to be subjected for elimination. - - int64 last_inspects; // Number of inspects since last removal of satified clauses in 'simplifyDB()' -- to avoid doing it too often. - - // Temporaries (to reduce allocation overhead): - // - vec seen_tmp; // (used in various places) - vec touched_tmp; // (used in 'simplifyBySubsumption()' to mark variables touched during elimination) - vec unit_tmp; // (used in 'addUnit()') - vec io_tmp; // (used for reading/writing clauses from/to disk) - - // Main internal methods: - // - void analyze (Clause confl, vec& out_learnt, int& out_btlevel); // (bt = backtrack) - bool enqueue (Lit fact, Clause from = NULL); - Clause propagate (void); - void propagateToplevel(void); - void reduceDB (void); - void compressDB (void); - Lit pickBranchLit (const SearchParams& params); - lbool search (int nof_conflicts, int nof_learnts, const SearchParams& params); - double progressEstimate (void); - void extendModel (void); - - // Clauses: - // - Clause allocClause (const vec& ps, bool learnt, Clause overwrite = Clause_NULL); - void deallocClause (Clause c, bool quick = false); - void unlinkClause (Clause c, Var elim = var_Undef); - bool propagateClause (Clause c, Lit p, bool& keep_watch); - void calcReason (Clause c, Lit p, vec& out_reason); - void strengthenClause(Clause c, Lit p); - - // Other database management: - // - void createTmpFiles(cchar* filename) { - if (filename == NULL) - elim_out = createTmpFile("/tmp/tmp_elims__", "w+b", elim_out_file); - else - elim_out = fopen(filename, "w+b"), - elim_out_file = NULL; } - void deleteTmpFiles(void) { if (elim_out_file != NULL) deleteTmpFile(elim_out_file, true); } - void registerIteration (vec& iter_vec) { iter_vecs.push(&iter_vec); } - void unregisterIteration(vec& iter_vec) { remove(iter_vecs, &iter_vec); } - void registerIteration (CSet& iter_set) { iter_sets.push(&iter_set); } - void unregisterIteration(CSet& iter_set) { remove(iter_sets, &iter_set); } - void setOccurMode(OccurMode occur_mode); - void setupWatches(void); - - // Activity: - // - void varBumpActivity(Lit p) { - if (var_decay < 0) return; // (negative decay means static variable order -- don't bump) - if ( (activity[var(p)] += var_inc) > 1e100 ) varRescaleActivity(); - #ifdef VAR_ORDER_2 - lt_activity[var(p)] += 1.0; - #endif - order.update(var(p)); } - void varDecayActivity(void) { if (var_decay >= 0) var_inc *= var_decay; } - void varRescaleActivity(void); - - void claBumpActivity(Clause c) { if ( (c.activity() += cla_inc) > 1e20 ) claRescaleActivity(); } - void claDecayActivity(void) { cla_inc *= cla_decay; } - void claRescaleActivity(void); - - // Helpers: - // - bool assume (Lit p); - void undoOne (void); - void cancel (void); - void cancelUntil (int level); - void record (const vec& clause); - bool locked (Clause c) { return reason[var(c[0])] == c; } - int decisionLevel(void) { return trail_lim.size(); } - - void watch (Clause c, Lit p) { watches[index(p)].push(c); } - void unwatch (Clause c, Lit p) { remove(watches[index(p)], c); } - - int allocClauseId(bool learnt); - void freeClauseId (int id, bool learnt); - - -// PUBLIC INTERFACE - - Solver(OccurMode mode = occ_Permanent, cchar* elimed_filename = NULL) - : ok (true) - , cla_inc (1) - , cla_decay (1) - , n_literals (0) - , var_inc (1) - , var_decay (1) - #ifdef VAR_ORDER_2 - , order (assigns, activity, lt_activity, var_inc) - #else - , order (assigns, activity) - #endif - , watches_setup (false) - , occur_mode (mode) - , root_level (0) - , last_simplify (-1) - , fwd_subsump (false) - , last_inspects (0) - , unit_tmp (1, lit_Undef) - , progress_estimate(0) - , verbosity(0) - { createTmpFiles(elimed_filename); - #ifndef WATCH_OPTIMIZATION - watches_setup = true; - #endif - } - ~Solver(void); - - // Helpers: (semi-internal) - // - lbool value(Var x) { return lbool(assigns[x]);/*toLbool(assigns[x]);*/ } - lbool value(Lit p) { return sign(p) ? ~lbool(assigns[var(p)]) : lbool(assigns[var(p)]);}//~toLbool(assigns[var(p)]) : toLbool(assigns[var(p)]); } - - int nAssigns (void) { return trail.size(); } - int nLiterals(void) { return n_literals; } - int nClauses (void) { return constrs.size() - constrs_free.size(); } - int nLearnts (void) { return learnts.size() - learnts_free.size(); } - - // Statistics: (read-only member variable) - // - SolverStats stats; - - // Problem specification: - // - Var newVar (void); - void setVars(int n_vars); - int nVars (void) { return assigns.size(); } - void addUnit(Lit p) { assert(unit_tmp.size() == 1); unit_tmp[0] = p; addClause(unit_tmp); } - - // -- constraints: - Clause addClause(const vec& ps, bool learnt = false, Clause overwrite = Clause_NULL); - void removeClause(Clause c, Var elim = var_Undef) { if (ok) { unlinkClause(c, elim); deallocClause(c); } } - - void freeze(Var x) { frozen[x] = 1; } - void thaw (Var x) { frozen[x] = 0; } - - // Solving: - // - bool okay(void) { return ok; } - void simplifyDB(bool subsume = false); - bool solve(const vec& assumps); - bool solve(void) { vec empty; return solve(empty); } - - double progress_estimate; // Set by 'search()'. - vec model; // If problem is solved, this vector contains the model (if any). - int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything - - // Subsumption: - // - void touch(Var x) { if (!touched[x]) touched[x] = 1, touched_list.push(x); } - void touch(Lit p) { touch(var(p)); } - bool updateOccur(Clause c) { return occur_mode == occ_All || (occur_mode == occ_Permanent && !c.learnt()); } - - int literalCount(void); // (just progress measure) - void findSubsumed(Clause ps, vec& out_subsumed); - bool isSubsumed(Clause ps); - bool hasClause(Clause ps); - void subsume0(Clause ps, int& counter = *(int*)NULL); - void subsume1(Clause ps, int& counter = *(int*)NULL); - void simplifyBySubsumption(bool with_var_elim = true); - - void orderVarsForElim(vec& order); - int substitute(Lit x, Clause def, vec& poss, vec& negs, vec& new_clauses); - Lit findUnitDef(Var x, vec& poss, vec& negs); - bool findDef(Lit x, vec& poss, vec& negs, Clause out_def); - bool maybeEliminate(Var x); - - void checkConsistency(void); - - void clauseReduction(void); - void asymmetricBranching(Lit p); - -}; - - -//================================================================================================= -// Debug: - - -// For derivation output (verbosity level 2) -#define L_IND "%-*d" -#define L_ind decisionLevel()*3+3,decisionLevel() -#define L_LIT "%sx%d" -#define L_lit(p) sign(p)?"~":"", var(p) - -// Just like 'assert()' but expression will be evaluated in the release version as well. -#ifdef NDEBUG - inline void check(bool expr) { assert(expr); } -#else - #define check assert -#endif - - -macro void dump(Clause c, bool newline = true, FILE* out = stdout) { - fprintf(out, "{"); - for (int i = 0; i < c.size(); i++) fprintf(out, " "L_LIT, L_lit(c[i])); - fprintf(out, " }%s", newline ? "\n" : ""); - fflush(out); -} -macro void dump(Solver& S, Clause c, bool newline = true, FILE* out = stdout) { - fprintf(out, "{"); - for (int i = 0; i < c.size(); i++) fprintf(out, " "L_LIT":%c", L_lit(c[i]), name(S.value(c[i]))); - fprintf(out, " }%s", newline ? "\n" : ""); - fflush(out); -} - -macro void dump(const vec& c, bool newline = true, FILE* out = stdout) { - fprintf(out, "{"); - for (int i = 0; i < c.size(); i++) fprintf(out, " "L_LIT, L_lit(c[i])); - fprintf(out, " }%s", newline ? "\n" : ""); - fflush(out); -} -macro void dump(Solver& S, vec& c, bool newline = true, FILE* out = stdout) { - fprintf(out, "{"); - for (int i = 0; i < c.size(); i++) fprintf(out, " "L_LIT":%c", L_lit(c[i]), name(S.value(c[i]))); - fprintf(out, " }%s", newline ? "\n" : ""); - fflush(out); -} - - -//================================================================================================= -#endif diff --git a/sources/SatElite/SatELite/SolverTypes.h b/sources/SatElite/SatELite/SolverTypes.h deleted file mode 100644 index cb45ded..0000000 --- a/sources/SatElite/SatELite/SolverTypes.h +++ /dev/null @@ -1,52 +0,0 @@ -/************************************************************************************************** - -SolverTypes.h -- (C) Niklas Een, Niklas Sörensson, 2004 - -Contains the solver specific types: Var, Lit. - -**************************************************************************************************/ - - -#ifndef SolverTypes_h -#define SolverTypes_h - -#ifndef Global_h -#include "Global.h" -#endif - - -//================================================================================================= -// Variables, literals: - - -// 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 int Var; -#define var_Undef (-1) - - -class Lit { - int x; -public: - Lit(void) /* unspecifed value allowed for efficiency */ { } - explicit Lit(Var var, bool sign = false) : x((var+var) + sign) { } - friend Lit operator ~ (Lit p) { Lit q; q.x = p.x ^ 1; return q; } - - friend bool sign (Lit p) { return p.x & 1; } - friend int var (Lit p) { return p.x >> 1; } - friend int index(Lit p) { return p.x; } // A "toInt" method that guarantees small, positive integers suitable for array indexing. - friend Lit toLit(int i); - - friend bool operator == (Lit p, Lit q) { return index(p) == index(q); } - friend bool operator < (Lit p, Lit q) { return index(p) < index(q); } // '<' guarantees that p, ~p are adjacent in the ordering. -}; - -inline Lit toLit(int i) { Lit p; p.x = i; return p; } -const Lit lit_Undef(var_Undef, false); // }- Useful special constants. -const Lit lit_Error(var_Undef, true ); // } - -macro uint64 abstLit(Lit p) { return ((uint64)1) << (index(p) & 63); } - -//================================================================================================= -#endif diff --git a/sources/SatElite/SatELite/Solver_clause.iC b/sources/SatElite/SatELite/Solver_clause.iC deleted file mode 100644 index 805a48e..0000000 --- a/sources/SatElite/SatELite/Solver_clause.iC +++ /dev/null @@ -1,386 +0,0 @@ -/************************************************************************************************** - -Solver_clause.iC -- (C) Niklas Een, Niklas Sörensson, 2004 - -ADT for clauses, the only constraint supported by Satelite. - -**************************************************************************************************/ - -#include "Solver.h" -#include "Sort.h" - - -//================================================================================================= -// Allocation: - - -#if 1 -// HACKISH OPTIMIZATION OF MEMORY ALLOCATION: - -#include "VecAlloc.h" -struct Size24 { char dummy[24]; }; -struct Size28 { char dummy[28]; }; -VecAlloc mem24; -VecAlloc mem28; - -template macro void* ymalloc(int size); -template <> void* ymalloc(int size) -{ - if (size == 24) return (void*)mem24.alloc(); - else if (size == 28) return (void*)mem28.alloc(); - else return (void*)xmalloc(size); -} - - -macro void yfree(void* ptr) -{ - Clause c((Clause_t*)ptr); - assert(!c.dynamic()); - int size = sizeof(Clause_t) + sizeof(uint)*(c.size() + (int)c.learnt()); - if (size == 24) mem24.free((Size24*)ptr); - else if (size == 28) mem28.free((Size28*)ptr); - else xfree(ptr); -} - -#else -#define ymalloc xmalloc -#define yfree xfree -#endif - -//================================================================================================= -// Solver methods operating on clauses: - - -// Will allocate space in 'constrs' or 'learnts' and return the position to put new clause at. -int Solver::allocClauseId(bool learnt) -{ - int id; - if (learnt){ - if (learnts_free.size() > 0) - id = learnts_free.last(), - learnts_free.pop(); - else - id = learnts.size(), - learnts.push(); - }else{ - if (constrs_free.size() > 0) - id = constrs_free.last(), - constrs_free.pop(); - else - id = constrs.size(), - constrs.push(); - } - return id; -} - - -void Solver::freeClauseId(int id, bool learnt) -{ - if (learnt){ - learnts[id] = Clause_NULL; - learnts_free.push(id); - }else{ - constrs[id] = Clause_NULL; - constrs_free.push(id); - } -} - - -Clause Solver::allocClause(const vec& ps, bool learnt, Clause overwrite) -{ - assert(sizeof(Lit) == sizeof(uint)); - assert(sizeof(float) == sizeof(uint)); - int id = overwrite.null() ? allocClauseId(learnt) : overwrite.id(); - void* mem = overwrite.null() ? ymalloc(sizeof(Clause_t) + sizeof(uint)*(ps.size() + (int)learnt)) : (void*)overwrite.ptr(); - Clause_t* c = new (mem) Clause_t; - - c->id_ = id; - c->abst_ = 0; - c->size_learnt = (int)learnt | (ps.size() << 1); - for (int i = 0; i < ps.size(); i++){ - c->data[i] = ps[i]; - c->abst_ |= abstLit(ps[i]); - } - if (learnt) Clause(c).activity() = 0.0; - - return Clause(c); -} - - -// PUBLIC: May return NULL if clause is already satisfied by the top-level assignment. -// -Clause Solver::addClause(const vec& ps_, bool learnt, Clause overwrite) -{ - if (!ok) return Clause_NULL; - - vec qs; - - // Contains no eliminated variables? - for (int i = 0; i < ps_.size(); i++) - assert(!var_elimed[var(ps_[i])]); - - if (!learnt){ - assert(decisionLevel() == 0); - ps_.copyTo(qs); // Make a copy of the input vector. - - // Remove false literals: - for (int i = 0; i < qs.size();){ - if (value(qs[i]) != l_Undef){ - if (value(qs[i]) == l_True){ - if (!overwrite.null()) deallocClause(overwrite); - return Clause_NULL; } // Clause always true -- don't add anything. - else - qs[i] = qs.last(), - qs.pop(); - }else - i++; - } - - // Remove duplicates: - sortUnique(qs); - for (int i = 0; i < qs.size()-1; i++){ - if (qs[i] == ~qs[i+1]){ - if (!overwrite.null()) deallocClause(overwrite); - return Clause_NULL; // Clause always true -- don't add anything. - } - } - } - const vec& ps = learnt ? ps_ : qs; // 'ps' is now the (possibly) reduced vector of literals. - //*HACK!*/if (ps.size() <= 3) learnt = false; - if (opt_keep_all) learnt = false; - - if (ps.size() == 0){ - if (!overwrite.null()) deallocClause(overwrite); - ok = false; - return Clause_NULL; - }else if (ps.size() == 1){ - if (!overwrite.null()) deallocClause(overwrite); - if (decisionLevel() > 0) units.push(ps[0]); - if (!enqueue(ps[0])){ - assert(decisionLevel() == 0); - ok = false; } - return Clause_NULL; } - else{ - // Allocate clause: - Clause c = allocClause(ps, learnt, overwrite); - - // Subsumption: - if (occur_mode != occ_Off){ - if (fwd_subsump && isSubsumed(c)){ - deallocClause(c); - return Clause_NULL; } - if (!learnt) subsume0(c); - } - - // Occur lists: - if (updateOccur(c)){ - for (int i = 0; i < ps.size(); i++) - occur[index(ps[i])].push(c), - touch(var(ps[i])); - if (overwrite.null()) - cl_added.add(c); - else - cl_touched.add(c); - } - - // For learnt clauses only: - if (learnt){ - // Put the second watch on the literal with highest decision level: - int max_i = 1; - int max = level[var(ps[1])]; - for (int i = 2; i < ps.size(); i++) - if (level[var(ps[i])] > max) - max = level[var(ps[i])], - max_i = i; - c[1] = ps[max_i]; - c[max_i] = ps[1]; - - // Bumping: - claBumpActivity(c); // (newly learnt clauses should be considered active) - } - //*TEST*/for (int i = 0; i < c.size(); i++) varBumpActivity(c[i]); - - // Attach clause: - if (watches_setup) - watch(c, ~c[0]), - watch(c, ~c[1]); - - if (learnt) learnts[c.id()] = c; - else constrs[c.id()] = c; - - if (!learnt){ - n_literals += c.size(); - for (int i = 0; i < c.size(); i++) - n_occurs[index(c[i])]++; - } - - return c; - } -} - - -void Solver::deallocClause(Clause c, bool quick) // (quick means only free memory; used in destructor of 'Solver') -{ - if (quick) - yfree(c.ptr()); - else{ - // Free resources: - freeClauseId(c.id(), c.learnt()); - yfree(c.ptr()); - } -} - - -void Solver::unlinkClause(Clause c, Var elim) -{ - if (elim != var_Undef){ - assert(!c.learnt()); - io_tmp.clear(); - io_tmp.push(toLit(c.size())); - for (int i = 0; i < c.size(); i++) - io_tmp.push(c[i]); - fwrite((Lit*)io_tmp, 4, io_tmp.size(), elim_out); - } - - if (updateOccur(c)){ - for (int i = 0; i < c.size(); i++){ - maybeRemove(occur[index(c[i])], c); - #ifndef TOUCH_LESS - touch(c[i]); - #endif - } - } - - if (watches_setup) - unwatch(c, ~c[0]), - unwatch(c, ~c[1]); - if (c.learnt()) learnts[c.id()] = Clause_NULL; - else constrs[c.id()] = Clause_NULL; - - if (!c.learnt()){ - n_literals -= c.size(); - for (int i = 0; i < c.size(); i++) - n_occurs[index(c[i])]--; - } - - // Remove from iterator vectors/sets: - for (int i = 0; i < iter_vecs.size(); i++){ - vec& cs = *iter_vecs[i]; - for (int j = 0; j < cs.size(); j++) - if (cs[j] == c) - cs[j] = NULL; - } - for (int i = 0; i < iter_sets.size(); i++){ - CSet& cs = *iter_sets[i]; - cs.exclude(c); - } - - // Remove clause from clause touched set: - if (updateOccur(c)) - cl_touched.exclude(c), - cl_added .exclude(c); - -} - - -// 'p' is the literal that became TRUE. Returns FALSE if conflict found. 'keep_watch' should be set -// to FALSE before call. It will be re-set to TRUE if the watch should be kept in the current -// watcher list. -// -bool Solver::propagateClause(Clause c, Lit p, bool& keep_watch) -{ - assert(watches_setup); - - // Make sure the false literal is c[1]: - Lit false_lit = ~p; - if (c(0) == false_lit) - c(0) = c(1), c(1) = false_lit; - assert(c(1) == false_lit); - - // If 0th watch is true, then clause is already satisfied. - if (value(c(0)) == l_True){ - keep_watch = true; - return true; } - - // Look for new watch: - for (int i = 2; i < c.size(); i++){ - if (value(c(i)) != l_False){ - c(1) = c(i), c(i) = false_lit; - watches[index(~c(1))].push(c); - return true; } } - - // Clause is unit under assignment: - keep_watch = true; - return enqueue(c(0), c); -} - - -// Can assume 'out_reason' to be empty. -// Calculate reason for 'p'. If 'p == lit_Undef', calculate reason for conflict. -// -void Solver::calcReason(Clause c, Lit p, vec& out_reason) -{ - assert(p == lit_Undef || p == c[0]); - for (int i = ((p == lit_Undef) ? 0 : 1); i < c.size(); i++) - assert(value(c[i]) == l_False), - out_reason.push(~c[i]); - if (c.learnt()) claBumpActivity(c); -} - - -// Will remove clause and add a new shorter, potentially unit and thus adding facts to propagation queue. -// -void Solver::strengthenClause(Clause c, Lit p) -{ - assert(c.size() > 1); - - vec new_clause; - for (int i = 0; i < c.size(); i++) - if (c[i] != p && (value(c[i]) != l_False || level[var(c[i])] > 0)) - new_clause.push(c[i]); - - unlinkClause(c); // (will touch all variables) - addClause(new_clause, c.learnt(), c); -} - - -//================================================================================================= -// Optimized occur table builder: - - -void Solver::setOccurMode(OccurMode new_occur_mode) -{ - assert(new_occur_mode != occ_All); // (not implemented) - occur_mode = new_occur_mode; - - if (occur_mode == occ_Off) - for (int i = 0; i < occur.size(); i++) - occur[i].clear(true); - else{ - assert(occur_mode == occ_Permanent); - // Allocate vectors of right capacities: - for (int i = 0; i < nVars()*2; i++){ - vec tmp(xmalloc(n_occurs[i]), n_occurs[i]); tmp.clear(); - tmp.moveTo(occur[i]); } - // Fill vectors: - for (int i = 0; i < constrs.size(); i++){ - if (constrs[i].null()) continue; - for (int j = 0; j < constrs[i].size(); j++) - assert(occur[index(constrs[i][j])].size() < n_occurs[index(constrs[i][j])]), - occur[index(constrs[i][j])].push(constrs[i]); - } - } -} - - -void Solver::setupWatches(void) -{ - if (watches_setup) return; - assert(learnts.size() == 0); - - for (int i = 0; i < constrs.size(); i++) - if (!constrs[i].null()) - watch(constrs[i], ~constrs[i][0]), - watch(constrs[i], ~constrs[i][1]); - watches_setup = true; -} diff --git a/sources/SatElite/SatELite/Solver_debug.C b/sources/SatElite/SatELite/Solver_debug.C deleted file mode 100644 index e5ee732..0000000 --- a/sources/SatElite/SatELite/Solver_debug.C +++ /dev/null @@ -1,46 +0,0 @@ -#include "Solver.h" - - -void Solver::checkConsistency(void) -{ - assert(occur_mode == occ_Permanent); // (we only worry about this mode for now) - - // Every constraint is present in the appropriate occurs tables: - for (int i = 0; i < constrs.size(); i++){ - Clause c = constrs[i]; if (c.null()) continue; - for (int j = 0; j < c.size(); j++) - if (occur[index(c[j])].size() > 0) - find(occur[index(c[j])], c); - } - - // Every occur list points to clauses containing the appropriate literals: - for (int i = 0; i < nVars()*2; i++){ - vec& cs = occur[i]; - Lit p = toLit(i); - for (int j = 0; j < cs.size(); j++) - find(cs[j], p); - } - - // DEBUG - if (0){ - printf("-----------------------------------------------------------------------------\n"); - vec freed(constrs.size(), false); - for (int i = 0; i < constrs_free.size(); i++){ - printf("MARKED FREE: %d\n", constrs_free[i]); - freed[constrs_free[i]] = true; } - for (int i = 0; i < constrs.size(); i++) - if (constrs[i].null()){ - printf("FREE: %d\n", i); - if (!freed[i]) printf("**MISSING**\n"), exit(1); - } - } - - // Null-clauses should be in the free lists: - vec freed(constrs.size(), false); - for (int i = 0; i < constrs_free.size(); i++) - assert(constrs[constrs_free[i]].null()), - freed[constrs_free[i]] = true; - - for (int i = 0; i < constrs.size(); i++) - assert(!constrs[i].null() || freed[i]); -} diff --git a/sources/SatElite/SatELite/Solver_subsume.C b/sources/SatElite/SatELite/Solver_subsume.C deleted file mode 100644 index ea13373..0000000 --- a/sources/SatElite/SatELite/Solver_subsume.C +++ /dev/null @@ -1,1159 +0,0 @@ -#include "Solver.h" -#include "Main.h" -#include "Sort.h" -#include "BcnfWriter.iC" - -#define Report(format, args...) ((verbosity >= 1) ? reportf(format , ## args) : 0) -//#define Report(format, args...) -#define Report2(format, args...) ((verbosity >= 2) ? reportf(format , ## args) : 0) - - -macro bool has(Clause c, Lit p) { - for (int i = 0; i < c.size(); i++) - if (c[i] == p) return true; - return false; } - - -#if 1 -// Assumes 'seen' is cleared (will leave it cleared) -static -bool subset(Clause A, Clause B, vec& seen) -{ - for (int i = 0; i < B.size(); i++) seen[index(B[i])] = 1; - for (int i = 0; i < A.size(); i++){ - if (!seen[index(A[i])]){ - for (int i = 0; i < B.size(); i++) seen[index(B[i])] = 0; - return false; - } - } - for (int i = 0; i < B.size(); i++) seen[index(B[i])] = 0; - return true; -} -#else -static -bool subset(Clause A, Clause B, vec& seen) -{ - for (int i = 0; i < A.size(); i++) - if (!has(B, A[i])) - return false; - return true; -} -#endif - - -macro bool subset(uint64 A, uint64 B) { return (A & ~B) == 0; } - - -// Assumes 'seen' is cleared (will leave it cleared) -static -bool selfSubset(Clause A, Clause B, vec& seen) -{ - for (int i = 0; i < B.size(); i++) seen[index(B[i])] = 1; - - bool flip = false; - for (int i = 0; i < A.size(); i++){ - if (!seen[index(A[i])]){ - if (flip == true || !seen[index(~A[i])]){ - for (int i = 0; i < B.size(); i++) seen[index(B[i])] = 0; - return false; - } - flip = true; - } - } - for (int i = 0; i < B.size(); i++) seen[index(B[i])] = 0; - return flip; -} - - -macro bool selfSubset(uint64 A, uint64 B) -{ - uint64 B_tmp = B | ((B & 0xAAAAAAAAAAAAAAAALL) >> 1) | ((B & 0x5555555555555555LL) << 1); - if ((A & ~B_tmp) == 0){ - uint64 C = A & ~B; - return (C & (C-1)) == 0; - }else - return false; -} - - -void Solver::findSubsumed(Clause ps, vec& out_subsumed) -{ - uint64 abst; - if (ps.dynamic()){ - abst = 0; - for (int i = 0; i < ps.size(); i++) - abst |= abstLit(ps[i]); - }else - abst = ps.abst(); - - int min_i = 0; - for (int i = 1; i < ps.size(); i++){ - if (occur[index(ps[i])].size() < occur[index(ps[min_i])].size()) - min_i = i; - } - - vec& cs = occur[index(ps[min_i])]; - for (int i = 0; i < cs.size(); i++){ - if (cs[i] != ps && ps.size() <= cs[i].size() && subset(abst, cs[i].abst()) && subset(ps, cs[i], seen_tmp)) - out_subsumed.push(cs[i]); - } -} - - -bool Solver::isSubsumed(Clause ps) -{ - uint64 abst; - if (ps.dynamic()){ - abst = 0; - for (int i = 0; i < ps.size(); i++) - abst |= abstLit(ps[i]); - }else - abst = ps.abst(); - - for (int j = 0; j < ps.size(); j++){ - vec& cs = occur[index(ps[j])]; - - for (int i = 0; i < cs.size(); i++){ - if (cs[i] != ps && cs[i].size() <= ps.size() && subset(cs[i].abst(), abst)){ - if (subset(cs[i], ps, seen_tmp)) - return true; - } - } - } - return false; -} - - -// Will put NULL in 'cs' if clause removed. -void Solver::subsume0(Clause ps, int& counter) -{ - if (!opt_0sub) return; - - vec subs; - findSubsumed(ps, subs); - for (int i = 0; i < subs.size(); i++){ - if (&counter != NULL) counter++; - removeClause(subs[i]); - } -} - - -#if 1 -// With queue -void Solver::subsume1(Clause ps, int& counter) -{ - if (!opt_1sub) return; - - vec Q; - vec subs; - Clause_t qs; - int q; - - registerIteration(Q); - registerIteration(subs); - - Q.push(ps); - q = 0; - while (q < Q.size()){ - if (Q[q].null()) { q++; continue; } - qs.clear(); - for (int i = 0; i < Q[q].size(); i++) - qs.push(Q[q][i]); - - for (int i = 0; i < qs.size(); i++){ - qs[i] = ~qs[i]; - findSubsumed(qs, subs); - for (int j = 0; j < subs.size(); j++){ - /*DEBUG*/ - #ifndef NDEBUG - if (&counter != NULL && counter == -1){ - dump(subs[j]); - qs[i] = ~qs[i]; - dump(qs); - printf(L_LIT"\n", L_lit(qs[i])); - exit(0); - } - #endif - /*END*/ - if (subs[j].null()) continue; - if (&counter != NULL) counter++; - strengthenClause(subs[j], qs[i]); - Q.push(subs[j]); - } - - qs[i] = ~qs[i]; - subs.clear(); - } - q++; - } - - unregisterIteration(Q); - unregisterIteration(subs); -} -#else -// Without queue -void Solver::subsume1(Clause ps, int& counter) -{ - if (!opt_1sub) return; - - vec subs; - Clause_t qs; - - registerIteration(subs); - - assert(!ps.null()); - for (int i = 0; i < ps.size(); i++) - qs.push(ps[i]); - - for (int i = 0; i < qs.size(); i++){ - qs[i] = ~qs[i]; - findSubsumed(qs, subs); - for (int j = 0; j < subs.size(); j++){ - if (subs[j].null()) continue; - if (&counter != NULL) counter++; - strengthenClause(subs[j], qs[i]); - } - - qs[i] = ~qs[i]; - subs.clear(); - } - unregisterIteration(subs); -} -#endif - - -void Solver::simplifyBySubsumption(bool with_var_elim) -{ - propagateToplevel(); if (!ok){ Report("(contradiction during subsumption)\n"); return; } - - int orig_n_clauses = nClauses(); - int orig_n_literals = nLiterals(); - do{ - // SUBSUMPTION: - // - #ifndef SAT_LIVE - Report(" -- subsuming \r"); - #endif - int clauses_subsumed = 0, literals_removed = 0; - if (!opt_0sub && !opt_1sub){ - cl_added .clear(); - cl_touched.clear(); - goto NoSubsumption; } - - if (cl_added.size() > nClauses() / 2){ - // Optimized variant when virtually whole database is involved: - cl_added .clear(); - cl_touched.clear(); - - for (int i = 0; i < constrs.size(); i++) if (!constrs[i].null()) subsume1(constrs[i], literals_removed); - propagateToplevel(); if (!ok){ Report("(contradiction during subsumption)\n"); return; } - - CSet s1; - registerIteration(s1); - while (cl_touched.size() > 0){ - for (int i = 0; i < cl_touched.size(); i++) - if (!cl_touched[i].null()) - s1.add(cl_touched[i]); - cl_touched.clear(); - - for (int i = 0; i < s1.size(); i++) if (!s1[i].null()) subsume1(s1[i], literals_removed); - s1.clear(); - - propagateToplevel(); - if (!ok){ Report("(contradiction during subsumption)\n"); unregisterIteration(s1); return; } - } - unregisterIteration(s1); - - for (int i = 0; i < constrs.size(); i++) if (!constrs[i].null()) subsume0(constrs[i], clauses_subsumed); - - }else{ - // Set used in 1-subs: - // (1) clauses containing a negated literal of an added clause. - // (2) all added or strengthened ("touched") clauses. - // - // Set used in 0-subs: - // (1) clauses containing a (non-negated) literal of an added clause, including the added clause itself. - // (2) all strenghtened clauses -- REMOVED!! We turned on eager backward subsumption which supersedes this. - -//Report(" PREPARING\n"); - CSet s0, s1; // 's0' is used for 0-subsumption, 's1' for 1-subsumption - vec ol_seen(nVars()*2, 0); - for (int i = 0; i < cl_added.size(); i++){ - Clause c = cl_added[i]; if (c.null()) continue; - s1.add(c); - for (int j = 0; j < c.size(); j++){ - if (ol_seen[index(c[j])]) continue; - ol_seen[index(c[j])] = 1; - - vec& n_occs = occur[index(~c[j])]; - for (int k = 0; k < n_occs.size(); k++) // <<= Bättra på. Behöver bara kolla 'n_occs[k]' mot 'c' - if (n_occs[k] != c && n_occs[k].size() <= c.size() && selfSubset(n_occs[k].abst(), c.abst()) && selfSubset(n_occs[k], c, seen_tmp)) - s1.add(n_occs[k]); - - vec& p_occs = occur[index(c[j])]; - for (int k = 0; k < p_occs.size(); k++) // <<= Bättra på. Behöver bara kolla 'p_occs[k]' mot 'c' - if (subset(p_occs[k].abst(), c.abst())) - s0.add(p_occs[k]); - } - } - cl_added.clear(); - - registerIteration(s0); - registerIteration(s1); - -//Report(" FIXED-POINT\n"); - // Fixed-point for 1-subsumption: - while (s1.size() > 0 || cl_touched.size() > 0){ - for (int i = 0; i < cl_touched.size(); i++) - if (!cl_touched[i].null()) - s1.add(cl_touched[i]), - s0.add(cl_touched[i]); - - cl_touched.clear(); - assert(propQ.size() == 0); -//Report("s1.size()=%d cl_touched.size()=%d\n", s1.size(), cl_touched.size()); - for (int i = 0; i < s1.size(); i++) if (!s1[i].null()){ subsume1(s1[i], literals_removed); } - s1.clear(); - - propagateToplevel(); - if (!ok){ - Report("(contradiction during subsumption)\n"); - unregisterIteration(s0); - unregisterIteration(s1); - return; } - assert(cl_added.size() == 0); - } - unregisterIteration(s1); - - // Iteration pass for 0-subsumption: - for (int i = 0; i < s0.size(); i++) if (!s0[i].null()) subsume0(s0[i], clauses_subsumed); - s0.clear(); - unregisterIteration(s0); - } - - if (literals_removed > 0 || clauses_subsumed > 0) - Report2(" #literals-removed: %d #clauses-subsumed: %d\n", literals_removed, clauses_subsumed); - - - // VARIABLE ELIMINATION: - // - NoSubsumption: - if (!with_var_elim || !opt_var_elim) break; - -//Report("VARIABLE ELIMINIATION\n"); - vec init_order; - orderVarsForElim(init_order); // (will untouch all variables) - - for (bool first = true;; first = false){ - int vars_elimed = 0; - int clauses_before = nClauses(); - vec order; - - if (opt_pure_literal){ - for (int i = 0; i < touched_list.size(); i++){ - Var x = touched_list[i]; - if (n_occurs[index(Lit(x))] == 0 && value(x) == l_Undef && !frozen[x] && !var_elimed[x] && n_occurs[index(~Lit(x))] > 0){ - enqueue(~Lit(x)); - }else if (n_occurs[index(~Lit(x))] == 0 && value(x) == l_Undef && !frozen[x] && !var_elimed[x] && n_occurs[index(Lit(x))] > 0){ - enqueue(Lit(x)); - } - } - propagateToplevel(); assert(ok); - } - - if (first) - init_order.copyTo(order); - else{ - for (int i = 0; i < touched_list.size(); i++) - if (!var_elimed[touched_list[i]]) - order.push(touched_list[i]), - touched[touched_list[i]] = 0; - touched_list.clear(); - } - - assert(propQ.size() == 0); - for (int i = 0; i < order.size(); i++){ - #ifndef SAT_LIVE - if (i % 1000 == 999 || i == order.size()-1) Report(" -- var.elim.: %d/%d \r", i+1, order.size()); - #endif - if (maybeEliminate(order[i])){ - vars_elimed++; - propagateToplevel(); if (!ok){ Report("(contradiction during subsumption)\n"); return; } - } - } - assert(propQ.size() == 0); - - if (vars_elimed == 0) - break; - - Report2(" #clauses-removed: %-8d #var-elim: %d\n", clauses_before - nClauses(), vars_elimed); - } - //assert(touched_list.size() == 0); // <<= No longer true, due to asymmetric branching. Ignore it for the moment... -// }while (cl_added.size() > 0); - }while (cl_added.size() > 100); - - if (orig_n_clauses != nClauses() || orig_n_literals != nLiterals()) - //Report("#clauses: %d -> %d #literals: %d -> %d (#learnts: %d)\n", orig_n_clauses, nClauses(), orig_n_literals, nLiterals(), nLearnts()); - //Report("#clauses:%8d (%6d removed) #literals:%8d (%6d removed) (#learnts:%8d)\n", nClauses(), orig_n_clauses-nClauses(), nLiterals(), orig_n_literals-nLiterals(), nLearnts()); - Report("| %9d | %7d %8d | %7s %7d %8s %7s | %6s | %d/%d\n", (int)stats.conflicts, nClauses(), nLiterals(), "--", nLearnts(), "--", "--", "--", nClauses() - orig_n_clauses, nLiterals() - orig_n_literals); - - - if (opt_pre_sat){ - // Compact variables: - vec vmap(nVars(), -1); - int c = 0; - for (int i = 0; i < nVars(); i++) - if (!var_elimed[i] && (occur[index(Lit(i))].size() != 0 || occur[index(~Lit(i))].size() != 0)) - vmap[i] = c++; - - Report("==============================================================================\n"); - Report("Result : #vars: %d #clauses: %d #literals: %d\n", c, nClauses(), nLiterals()); - Report("CPU time: %g s\n", cpuTime()); - Report("==============================================================================\n"); - - // Write CNF or BCNF file: - cchar* filename = (output_file == NULL) ? "pre-satelited.cnf" : output_file; - int len = strlen(filename); - if (len >= 5 && strcmp(filename+len-5, ".bcnf") == 0){ - BcnfWriter w(filename); - vec lits; - for (int i = 0; i < constrs.size(); i++){ - Clause c = constrs[i]; if (c.null()) continue; - lits.clear(); lits.growTo(c.size()); - for (int j = 0; j < c.size(); j++) - lits[j] = Lit(vmap[var(c[j])], sign(c[j])); - w.addClause(lits); - } - }else{ - FILE* out = (strcmp(filename, "-") == 0) ? stdout : fopen(filename, "wb"); - if (out == NULL) fprintf(stderr, "ERROR! Could not open output file: %s\n", filename), exit(1); - - fprintf(out, "c #vars: %d #clauses: %d #literals: %d\n" , c, nClauses(), nLiterals()); - fprintf(out, "c \n"); - fprintf(out, "p cnf %d %d\n", c, nClauses()); - for (int i = 0; i < constrs.size(); i++){ - Clause c = constrs[i]; if (c.null()) continue; - for (int j = 0; j < c.size(); j++) - assert(vmap[var(c[j])]+1 != -1), - fprintf(out, "%s%d ", sign(c[j])?"-":"", vmap[var(c[j])]+1); - fprintf(out, "0\n"); - } - fclose(out); - } - - // Write varible map: - if (varmap_file != NULL){ - FILE* out = fopen(varmap_file, "wb"); - if (out == NULL) fprintf(stderr, "ERROR! Could not open output file: %s\n", varmap_file), exit(1); - - fprintf(out, "%d 0\n", nVars()); - - c = 0; - for (int i = 0; i < nVars(); i++){ - if (!var_elimed[i] && value(i) != l_Undef){ - c++; - fprintf(out, "%s%s%d", (c > 1)?" ":"", (value(i)==l_True)?"":"-", i+1); - } - } - fprintf(out, " 0\n"); - - c = 0; - for (int i = 0; i < nVars(); i++){ - if (vmap[i] != -1){ - assert(vmap[i] == c); - c++; - fprintf(out, "%s%d", (c > 1)?" ":"", i+1); - } - } - fprintf(out, " 0\n"); - fclose(out); - } - fflush(elim_out); - exit(0); - } - -//Report("DONE!\n"); -} - - - - - -//================================================================================================= -// Eliminate variables: - - -// Side-effect: Will untouch all variables. -void Solver::orderVarsForElim(vec& order) -{ - order.clear(); - vec > cost_var; - for (int i = 0; i < touched_list.size(); i++){ - Var x = touched_list[i]; - touched[x] = 0; - cost_var.push(Pair_new( occur[index(Lit(x))].size() * occur[index(~Lit(x))].size() , x )); - } - touched_list.clear(); - sort(cost_var); - - for (int x = 0; x < cost_var.size(); x++) - if (cost_var[x].fst != 0) - order.push(cost_var[x].snd); -} - - -#if 0 -// Returns FALSE if clause is always satisfied ('out_clause' should not be used). -static -bool merge(Clause ps, Clause qs, Lit without_p, Lit without_q, vec& out_clause) -{ - int i = 0, j = 0; - while (i < ps.size() && j < qs.size()){ - if (ps[i] == without_p) i++; - else if (qs[j] == without_q) j++; - else if (ps[i] == ~qs[j]) return false; - else if (ps[i] < qs[j]) out_clause.push(ps[i++]); - else if (ps[i] > qs[j]) out_clause.push(qs[j++]); - else out_clause.push(ps[i++]), j++; - } - while (i < ps.size()){ - if (ps[i] == without_p) i++; - else out_clause.push(ps[i++]); } - while (j < qs.size()){ - if (qs[j] == without_q) j++; - else out_clause.push(qs[j++]); } - return true; -} -#endif - -// Returns FALSE if clause is always satisfied ('out_clause' should not be used). 'seen' is assumed to be cleared. -static -bool merge(Clause ps, Clause qs, Lit without_p, Lit without_q, vec& seen, vec& out_clause) -{ - for (int i = 0; i < ps.size(); i++){ - if (ps[i] != without_p){ - seen[index(ps[i])] = 1; - out_clause.push(ps[i]); - } - } - - for (int i = 0; i < qs.size(); i++){ - if (qs[i] != without_q){ - if (seen[index(~qs[i])]){ - for (int i = 0; i < ps.size(); i++) seen[index(ps[i])] = 0; - return false; } - if (!seen[index(qs[i])]) - out_clause.push(qs[i]); - } - } - - for (int i = 0; i < ps.size(); i++) seen[index(ps[i])] = 0; - return true; -} - - -Lit Solver::findUnitDef(Var x, vec& poss, vec& negs) -{ - vec imps; // All p:s s.t. "~x -> p" - for (int i = 0; i < poss.size(); i++){ - if (poss[i].size() == 2){ - if (var(poss[i][0]) == x) - imps.push(poss[i][1]); - else - assert(var(poss[i][1]) == x), - imps.push(poss[i][0]); - } - } - - // Quadratic algorithm; maybe should improve? - for (int i = 0; i < negs.size(); i++){ - if (negs[i].size() == 2){ - Lit p = (var(negs[i][0]) == x ) ? ~negs[i][1] : (assert(var(negs[i][1]) == x), ~negs[i][0]); - for (int j = 0; j < imps.size(); j++) - if (imps[j] == p) - return ~imps[j]; - //**/else if (imps[j] == ~p) - //**/ enqueue(~p); - } - } - - return lit_Undef; -} - - -// If returns TRUE 'out_def' is the definition of 'x' (always a disjunction). -// An empty definition means '~x' is globally true. -// -bool Solver::findDef(Lit x, vec& poss, vec& negs, Clause out_def) -{ - assert(out_def.size() == 0); - Clause_t imps; // (negated implied literals, actually) - uint64 abst = 0; - - for (int i = 0; i < negs.size(); i++){ - if (negs[i].size() == 2){ - Lit imp; - if (negs[i][0] == ~x) - imp = ~negs[i][1]; - else - assert(negs[i][1] == ~x), - imp = ~negs[i][0]; - - imps.push(imp); - abst |= abstLit(imp); - } - } - - if (opt_hyper1_res && isSubsumed(imps)) - return true; - if (!opt_def_elim) - return false; - - imps.push(x); - abst |= abstLit(x); - - for (int i = 0; i < poss.size(); i++){ - if (subset(poss[i].abst(), abst) && subset(poss[i], imps, seen_tmp)){ - Clause c = poss[i]; - - if (out_def.size() > 0 && c.size()-1 < out_def.size()) - //**/printf("----------\nImps : "), dump(imps),printf("Before: "), dump(out_def), printf("Now : "), dump(c, false), printf(" -- minus "L_LIT"\n", L_lit(x)); - out_def.clear(); // (found a better definition) - if (out_def.size() == 0){ - for (int j = 0; j < c.size(); j++) - if (c[j] != x) - out_def.push(~c[j]); - assert(out_def.size() == c.size()-1); - } - } - } - return (out_def.size() > 0); -} - -/* - - 1 2 3 -3 -4 - 1 -2 3 resolved with -3 -5 - 4 5 3 -3 6 7 - -3 -6 -7 - -3 -> ~4 == { ~3, ~4 } (ger ~4, ~5 + ev mer som superset; negera detta och lägg till 3:an) -3 -> ~5 == { ~3, ~5 } - -~4 & ~5 -> 3 == { 4, 5, 3 } -*/ - -int Solver::substitute(Lit x, Clause def, vec& poss, vec& negs, vec& new_clauses = *(vec*)NULL) -{ - vec tmp; - int counter = 0; - - - // Positives: - //**/if (hej) printf(" --from POS--\n"); - for (int i = 0; i < def.size(); i++){ - for (int j = 0; j < poss.size(); j++){ - if (poss[j].null()) continue; - - Clause c = poss[j]; - for (int k = 0; k < c.size(); k++){ - if (c[k] == ~def[i]) - goto Skip; - } - tmp.clear(); - for (int k = 0; k < c.size(); k++){ - if (c[k] == x) - tmp.push(def[i]); - else - tmp.push(c[k]); - } - //**/if (hej) printf(" "), dump(*this, tmp); - if (&new_clauses != NULL){ - Clause tmp_c; - tmp_c = addClause(tmp); - if (!tmp_c.null()) - new_clauses.push(tmp_c); - }else{ - sortUnique(tmp); - for (int i = 0; i < tmp.size()-1; i++) - if (tmp[i] == ~tmp[i+1]) - goto Skip; - counter++; - } - Skip:; - } - } - //**/if (hej) printf(" --from NEG--\n"); - - // Negatives: - for (int j = 0; j < negs.size(); j++){ - if (negs[j].null()) continue; - - Clause c = negs[j]; - // If any literal from 'def' occurs in 'negs[j]', it is satisfied. - for (int i = 0; i < def.size(); i++){ - if (has(c, def[i])) - goto Skip2; - } - - tmp.clear(); - for (int i = 0; i < c.size(); i++){ - if (c[i] == ~x){ - for (int k = 0; k < def.size(); k++) - tmp.push(~def[k]); - }else - tmp.push(c[i]); - } - //**/if (hej) printf(" "), dump(*this, tmp); - if (&new_clauses != NULL){ - Clause tmp_c; - tmp_c = addClause(tmp); - if (!tmp_c.null()) - new_clauses.push(tmp_c); - }else{ - sortUnique(tmp); - for (int i = 0; i < tmp.size()-1; i++) - if (tmp[i] == ~tmp[i+1]) - goto Skip2; - counter++; - } - Skip2:; - } - - //**/if (counter != 0 && def.size() >= 2) exit(0); - return counter; -} - - -void Solver::asymmetricBranching(Lit p) -{ - if (!opt_asym_branch) return; - - assert(decisionLevel() == 0); - propagateToplevel(); if (!ok){ Report("(contradiction during asymmetric branching)\n"); return; } - - vec learnt; - //vec& seen = seen_tmp; - vec cs; - occur[index(p)].copyTo(cs); - registerIteration(cs); - - for (int i = 0; i < cs.size(); i++){ - Clause c = cs[i]; if (c.null()) continue; - -#if 1 - Clause confl; - bool analyze = false; - - //**/printf("Inspecting: "); dump(*this, c); - for (int j = 0; j < c.size(); j++){ - if (c[j] == p) continue; - Lit q = ~c[j]; - //**/printf("Assuming: "L_LIT"\n", L_lit(q)); - if (!assume(q)){ - //**/printf("Assumption failed!\n"); - learnt.clear(); - if (level[var(q)] > 0) - learnt.push(~q); - Clause rs = reason[var(q)]; - for (int k = 1; k < rs.size(); k++){ - assert(value(rs[k]) == l_False); - seen_tmp[index(~rs[k])] = 1; } - analyze = true; - break; - } - - confl = propagate(); - if (!confl.null()){ - //**/printf("Lead to conflict! "); dump(*this, confl); - learnt.clear(); - for (int k = 0; k < confl.size(); k++){ - assert(value(confl[k]) == l_False); - seen_tmp[index(~confl[k])] = 1; } - analyze = true; - break; - } - } - - if (analyze){ - // Analyze conflict: - for (int j = trail.size()-1; j >= 0; j--){ - Lit q = trail[j]; - if (seen_tmp[index(q)]){ - Clause rs = reason[var(q)]; - if (rs.null()){ - if (level[var(q)] > 0) - learnt.push(~q); - }else{ - for (int k = 1; k < rs.size(); k++) - seen_tmp[index(~rs[k])] = 1; - } - seen_tmp[index(q)] = 0; - } - } - } - - cancelUntil(0); - - /*Test 'seen[]'*/ - //for (int i = 0; i < seen.size(); i++) assert(seen[i] == 0); - /*End*/ - - if (analyze){ - // Update clause: - //**/printf("%d ", c.size() - learnt.size()); fflush(stdout); - //**/{static int counter = 0; static const char chr[] = { '|', '/', '-', '\\' }; printf("%c\r", chr[counter++ & 3]); fflush(stdout); } - assert(propQ.size() == 0); - /*Test Subset*/ - #ifndef NDEBUG - for (int i = 0; i < learnt.size(); i++){ - for (int j = 0; j < c.size(); j++) - if (c[j] == learnt[i]) - goto Found; - printf("\n"); - printf("asymmetricBranching("L_LIT" @ %d)\n", L_lit(p), level[var(p)]); - printf("learnt: "); dump(*this, learnt); - printf("c : "); dump(*this, c ); - assert(false); // no subset! - Found:; - } - #endif - /*End*/ - unlinkClause(c); // (will touch all variables) - addClause(learnt, false, c); - propagateToplevel(); if (!ok){ Report("(contradiction during asymmetric branching after learning unit fact)\n"); return; } - } - -#else - assert(propQ.size() == 0); - bool conflict = false; - for (int j = 0; j < c.size(); j++){ - if (c[j] == p) continue; - if (!assume(~c[j])) { conflict = true; break; } - if (!propagate().null()) { conflict = true; break; } - } - assert(propQ.size() == 0); - cancelUntil(0); - - if (conflict){ - /**/putchar('+'); fflush(stdout); - //**/printf("----------------------------------------\n"); - //**/printf("asymmetricBranching("L_LIT" @ %d)\n", L_lit(p), level[var(p)]); - //**/dump(*this, c); - //**/for (int j = 0; j < c.size(); j++) if (c[j] == p) goto Found; assert(false); Found:; - assert(!cs[i].null()); - strengthenClause(c, p); - propagateToplevel(); if (!ok){ Report("(contradiction during asymmetric branching after learning unit fact)\n"); return; } - } -#endif - } - - unregisterIteration(cs); - assert(propQ.size() == 0); -} - - -// Returns TRUE if variable was eliminated. -bool Solver::maybeEliminate(Var x) -{ - assert(propQ.size() == 0); - assert(!var_elimed[x]); - if (frozen[x]) return false; - if (value(x) != l_Undef) return false; - if (occur[index(Lit(x))].size() == 0 && occur[index(~Lit(x))].size() == 0) return false; - - vec& poss = occur[index( Lit(x))]; - vec& negs = occur[index(~Lit(x))]; - vec new_clauses; - - int before_clauses = -1; - int before_literals = -1; - - bool elimed = false; - bool tried_elim = false; - - #define MigrateToPsNs vec ps; poss.moveTo(ps); vec ns; negs.moveTo(ns); for (int i = 0; i < ps.size(); i++) unlinkClause(ps[i], x); for (int i = 0; i < ns.size(); i++) unlinkClause(ns[i], x); - #define DeallocPsNs for (int i = 0; i < ps.size(); i++) deallocClause(ps[i]); for (int i = 0; i < ns.size(); i++) deallocClause(ns[i]); - - // Find 'x <-> p': - if (opt_unit_def){ - Lit p = findUnitDef(x, poss, negs); - /**/if (p == lit_Undef) propagateToplevel(); if (!ok) return true; - if (p != lit_Undef){ - //**/printf("DEF: x%d = "L_LIT"\n", x, L_lit(p)); - /*BEG - printf("POS:\n"); for (int i = 0; i < poss.size(); i++) printf(" "), dump(poss[i]); - printf("NEG:\n"); for (int i = 0; i < negs.size(); i++) printf(" "), dump(negs[i]); - printf("DEF: x%d = "L_LIT"\n", x, L_lit(p)); - hej = true; - END*/ - Clause_t def; def.push(p); - MigrateToPsNs - substitute(Lit(x), def, ps, ns, new_clauses); - /*BEG - hej = false; - printf("NEW:\n"); - for (int i = 0; i < new_clauses.size(); i++) - printf(" "), dump(new_clauses[i]); - END*/ - propagateToplevel(); if (!ok) return true; - DeallocPsNs - goto Eliminated; - } - } - - // ... -#if 0 - if (poss.size() < 10){ asymmetricBranching( Lit(x)); if (!ok) return true; } - if (negs.size() < 10){ asymmetricBranching(~Lit(x)); if (!ok) return true; } - if (value(x) != l_Undef) return false; -#endif - - // Heuristic: - if (poss.size() >= 8 && negs.size() >= 8) // <<== CUT OFF -// if (poss.size() >= 7 && negs.size() >= 7) // <<== CUT OFF -// if (poss.size() >= 6 && negs.size() >= 6) // <<== CUT OFF - return false; - - // Count clauses/literals before elimination: - before_clauses = poss.size() + negs.size(); - before_literals = 0; - for (int i = 0; i < poss.size(); i++) before_literals += poss[i].size(); - for (int i = 0; i < negs.size(); i++) before_literals += negs[i].size(); - - if (poss.size() >= 3 && negs.size() >= 3 && before_literals > 300) // <<== CUT OFF - return false; - - // Check for definitions: - if (opt_def_elim || opt_hyper1_res){ - //if (poss.size() > 1 || negs.size() > 1){ - if (poss.size() > 2 || negs.size() > 2){ - Clause_t def; - int result_size; - if (findDef(Lit(x), poss, negs, def)){ - if (def.size() == 0){ enqueue(~Lit(x)); return true; } // Hyper-1-resolution - result_size = substitute(Lit(x), def, poss, negs); - if (result_size <= poss.size() + negs.size()){ // <<= elimination threshold (maybe subst. should return literal count as well) - MigrateToPsNs - substitute(Lit(x), def, ps, ns, new_clauses); - propagateToplevel(); if (!ok) return true; - DeallocPsNs - goto Eliminated; - }else - tried_elim = true, - def.clear(); - } - if (!elimed && findDef(~Lit(x), negs, poss, def)){ - if (def.size() == 0){ enqueue(Lit(x)); return true; } // Hyper-1-resolution - result_size = substitute(~Lit(x), def, negs, poss); - if (result_size <= poss.size() + negs.size()){ // <<= elimination threshold - MigrateToPsNs - substitute(~Lit(x), def, ns, ps, new_clauses); - propagateToplevel(); if (!ok) return true; - DeallocPsNs - goto Eliminated; - }else - tried_elim = true; - } - } - } - - if (!tried_elim){ - // Count clauses/literals after elimination: - int after_clauses = 0; - int after_literals = 0; - Clause_t dummy; - for (int i = 0; i < poss.size(); i++){ - for (int j = 0; j < negs.size(); j++){ - // Merge clauses. If 'y' and '~y' exist, clause will not be created. - dummy.clear(); - bool ok = merge(poss[i], negs[j], Lit(x), ~Lit(x), seen_tmp, dummy.asVec()); - if (ok){ - after_clauses++; - /**/if (after_clauses > before_clauses) goto Abort; - after_literals += dummy.size(); } - } - } - Abort:; - - // Maybe eliminate: - if ((!opt_niver && after_clauses <= before_clauses) - || ( opt_niver && after_literals <= before_literals) - ){ - MigrateToPsNs - for (int i = 0; i < ps.size(); i++){ - for (int j = 0; j < ns.size(); j++){ - dummy.clear(); - bool ok = merge(ps[i], ns[j], Lit(x), ~Lit(x), seen_tmp, dummy.asVec()); - if (ok){ - Clause c = addClause(dummy.asVec()); - if (!c.null()){ - new_clauses.push(c); } - propagateToplevel(); if (!ok) return true; - } - } - } - DeallocPsNs - goto Eliminated; - } - - /*****TEST*****/ -#if 1 - // Try to remove 'x' from clauses: - bool ran = false; - if (poss.size() < 10){ ran = true; asymmetricBranching( Lit(x)); if (!ok) return true; } - if (negs.size() < 10){ ran = true; asymmetricBranching(~Lit(x)); if (!ok) return true; } - if (value(x) != l_Undef) return false; - if (!ran) return false; - - { - // Count clauses/literals after elimination: - int after_clauses = 0; - int after_literals = 0; - Clause_t dummy; - for (int i = 0; i < poss.size(); i++){ - for (int j = 0; j < negs.size(); j++){ - // Merge clauses. If 'y' and '~y' exist, clause will not be created. - dummy.clear(); - bool ok = merge(poss[i], negs[j], Lit(x), ~Lit(x), seen_tmp, dummy.asVec()); - if (ok){ - after_clauses++; - after_literals += dummy.size(); } - } - } - - // Maybe eliminate: - if ((!opt_niver && after_clauses <= before_clauses) - || ( opt_niver && after_literals <= before_literals) - ){ - MigrateToPsNs - for (int i = 0; i < ps.size(); i++){ - for (int j = 0; j < ns.size(); j++){ - dummy.clear(); - bool ok = merge(ps[i], ns[j], Lit(x), ~Lit(x), seen_tmp, dummy.asVec()); - if (ok){ - Clause c = addClause(dummy.asVec()); - if (!c.null()){ - new_clauses.push(c); } - propagateToplevel(); if (!ok) return true; - } - } - } - DeallocPsNs - goto Eliminated; - } - } -#endif - /*****END TEST*****/ - } - - return false; - - Eliminated: - assert(occur[index(Lit(x))].size() + occur[index(~Lit(x))].size() == 0); - var_elimed[x] = 1; - assigns [x] = toInt(l_Error); - return true; -} - - -// Inefficient test implementation! (pre-condition: satisfied clauses have been removed) -// -void Solver::clauseReduction(void) -{ - /**/reportf("clauseReduction() -- BEGIN\n"); - assert(decisionLevel() == 0); - propagateToplevel(); if (!ok){ Report("(contradiction during clause reduction)\n"); return; } - - vec learnt; - vec& seen = seen_tmp; - - for (int i = 0; i < constrs.size(); i++){ - Clause c = constrs[i]; if (c.null()) continue; - Clause confl; - bool analyze = false; - - //**/dump(*this, c); - unwatch(c, ~c[0]); - unwatch(c, ~c[1]); - for (int j = 0; j < c.size(); j++){ - //**/printf(L_LIT" = %c\n", L_lit(c[j]), name(value(c[j]))); - - if (!assume(~c[j])){ - learnt.clear(); - if (level[var(c[j])] > 0) - learnt.push(c[j]); - Clause rs = reason[var(c[j])]; - for (int k = 1; k < rs.size(); k++){ - assert(value(rs[k]) == l_False); - seen[index(~rs[k])] = 1; } - analyze = true; - break; - } - - confl = propagate(); - if (!confl.null()){ - learnt.clear(); - for (int k = 0; k < confl.size(); k++){ - assert(value(confl[k]) == l_False); - seen[index(~confl[k])] = 1; } - analyze = true; - break; - } - } - - if (analyze){ - // Analyze conflict: - for (int j = trail.size()-1; j >= 0; j--){ - Lit p = trail[j]; - if (seen[index(p)]){ - Clause rs = reason[var(p)]; - if (rs.null()){ - if (level[var(p)] > 0) - learnt.push(~p); - }else{ - for (int k = 1; k < rs.size(); k++) - seen[index(~rs[k])] = 1; - } - seen[index(p)] = 0; - } - } - - // (kolla att seen[] är nollad korrekt här) - - /**/if (learnt.size() < c.size()){ - putchar('*'); fflush(stdout); - //**/printf("Original: "); dump(c); - //**/printf("Conflict:"); - //**/for (int j = 0; j < learnt.size(); j++) printf(" "L_LIT, L_lit(learnt[j])); - //**/printf("\n"); - //**/if (learnt.size() == 0) exit(0); - /**/} - } - - cancelUntil(0); - watch(c, ~c[0]); - watch(c, ~c[1]); - - if (analyze && learnt.size() < c.size()){ - // Update clause: - //**/printf("{"); for (int i = 0; i < c.size(); i++) printf(" %d", occur[index(c[i])].size()); printf(" }\n"); - - /**/assert(propQ.size() == 0); - /*Test Subset*/ - for (int i = 0; i < learnt.size(); i++){ - for (int j = 0; j < c.size(); j++) - if (c[j] == learnt[i]) - goto Found; - assert(false); // no subset! - Found:; - } - /*End*/ - unlinkClause(c); // (will touch all variables) - addClause(learnt, false, c); - propagateToplevel(); if (!ok){ Report("(contradiction during clause reduction after learning unit fact)\n"); return; } - /**/assert(propQ.size() == 0); - } - //**/else{ printf(" {"); for (int i = 0; i < c.size(); i++) printf(" %d", occur[index(c[i])].size()); printf(" }\n"); } - } - /**/reportf("clauseReduction() -- END\n"); -} diff --git a/sources/SatElite/SatELite/TmpFiles.C b/sources/SatElite/SatELite/TmpFiles.C deleted file mode 100644 index 58d1555..0000000 --- a/sources/SatElite/SatELite/TmpFiles.C +++ /dev/null @@ -1,62 +0,0 @@ -#include "TmpFiles.h" - - -static vec tmp_fps; -static vec tmp_files; - - -// 'out_name' should NOT be freed by caller. -FILE* createTmpFile(cchar* prefix, cchar* mode, char* out_name) -{ - char* name = xmalloc(strlen(prefix) + 6 + 1); - strcpy(name, prefix); - strcat(name, "XXXXXX"); - - int fd = mkstemp(name); - if (fd == -1){ - fprintf(stderr, "ERROR! Could not create temporary file with prefix: %s\n", prefix); - exit(1); } - FILE* fp = fdopen(fd, mode); assert(fp != NULL); - - tmp_fps .push(fp); - tmp_files.push(name); - if (&out_name != NULL) out_name = name; - return fp; -} - - -// If 'exact' is set, 'prefix' is the full name returned by 'createTmpFile()'. -void deleteTmpFile(cchar* prefix, bool exact) -{ - uint len = strlen(prefix); - for (int i = 0; i < tmp_files.size();){ - if (!exact && (strlen(tmp_files[i]) == len + 6 && strncmp(tmp_files[i], prefix, len) == 0) - || exact && (strcmp(tmp_files[i], prefix) == 0)) - { - fclose(tmp_fps[i]); - remove(tmp_files[i]); - xfree(tmp_files[i]); - tmp_fps[i] = tmp_fps.last(); - tmp_fps.pop(); - tmp_files[i] = tmp_files.last(); - tmp_files.pop(); - }else - i++; - } -} - - -// May be used to delete all temporaries. Will also be called automatically upon (normal) program exit. -void deleteTmpFiles(void) -{ - for (int i = 0; i < tmp_fps.size(); i++){ - fclose(tmp_fps[i]); - remove(tmp_files[i]); - xfree(tmp_files[i]); - } -} - - -FINALIZER(TmpFiles) { - deleteTmpFiles(); -} diff --git a/sources/SatElite/SatELite/TmpFiles.h b/sources/SatElite/SatELite/TmpFiles.h deleted file mode 100644 index 68a9cd9..0000000 --- a/sources/SatElite/SatELite/TmpFiles.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef TmpFiles_h -#define TmpFiles_h - -//================================================================================================= - - -FILE* createTmpFile(cchar* prefix, cchar* mode, char* out_name = *(char**)NULL); -void deleteTmpFile(cchar* prefix, bool exact = false); -void deleteTmpFiles(void); - - -//================================================================================================= -#endif diff --git a/sources/SatElite/SatELite/VarOrder.h b/sources/SatElite/SatELite/VarOrder.h deleted file mode 100644 index aa89994..0000000 --- a/sources/SatElite/SatELite/VarOrder.h +++ /dev/null @@ -1,107 +0,0 @@ -/************************************************************************************************** - -VarOrder.h -- (C) Niklas Een, Niklas Sörensson, 2004 - -ADT for maintaining the variable ordering. It will keep a list of all decision -variables sorted on the current activity. - -**************************************************************************************************/ - -#ifndef VarOrder_h -#define VarOrder_h - -#include "SolverTypes.h" -#include "Heap.h" - -//================================================================================================= - - -struct VarOrder_lt { - const vec& activity; - bool operator () (Var x, Var y) { return activity[x] > activity[y]; } - VarOrder_lt(const vec& act) : activity(act) { } -}; - -struct VarOrder { - const vec& assigns; // var->val. Pointer to external assignment table. - const vec& activity; // var->act. Pointer to external activity table. - Heap heap; - double random_seed; // For the internal random number generator - -//public: - VarOrder(const vec& ass, const vec& act) : - assigns(ass), activity(act), heap(VarOrder_lt(act)), random_seed(91648253) {} - - inline void newVar(void); - inline void update(Var x); // Called when variable increased in activity. - inline void undo(Var x); // Called when variable is unassigned and may be selected again. - inline Var select(double random_freq =.0); // Selects a new, unassigned variable (or 'var_Undef' if none exists). - inline Var peekSelect(void); // Return next variable that will be selected if 'random_freq' is set to 0. -}; - - -void VarOrder::newVar(void) -{ - heap.setBounds(assigns.size()); - heap.insert(assigns.size()-1); -} - - -void VarOrder::update(Var x) -{ - if (heap.inHeap(x)) - heap.increase(x); -} - - -void VarOrder::undo(Var x) -{ - if (!heap.inHeap(x)) - heap.insert(x); -} - - -Var VarOrder::select(double random_var_freq) -{ - // Random decision: - if (drand(random_seed) < random_var_freq){ - Var next = irand(random_seed,assigns.size()); - if (lbool(assigns[next]) == l_Undef) - return next; - } - - // Activity based decision: - while (!heap.empty()){ - Var next = heap.getmin(); - if (lbool(assigns[next]) == l_Undef) - return next; - } - - return var_Undef; -} - -Var VarOrder::peekSelect(void) { return heap.peekmin(); } - - -//================================================================================================= -// A hack! - - -class VarOrder2 { - VarOrder st, lt; // Short term, long term. - const double& act_inc; -public: - VarOrder2(const vec& ass, const vec& st_act, const vec& lt_act, double& act_inc_) : st(ass, st_act), lt(ass, lt_act), act_inc(act_inc_) {} - - void newVar(void) { st.newVar() ; lt.newVar() ; } - void update(Var x) { st.update(x); lt.update(x); } - void undo(Var x) { st.undo(x) ; lt.undo(x) ; } - Var select(double r = 0) { - Var x = st.peekSelect(); - return (st.activity[x] / act_inc < 0.2) ? lt.select(r) : st.select(); - } -}; - - -//================================================================================================= -#endif diff --git a/sources/glucose/utils/Makefile b/utils/Makefile similarity index 100% rename from sources/glucose/utils/Makefile rename to utils/Makefile diff --git a/sources/glucose/utils/Options.cc b/utils/Options.cc similarity index 92% rename from sources/glucose/utils/Options.cc rename to utils/Options.cc index cb4df61..73d7f58 100644 --- a/sources/glucose/utils/Options.cc +++ b/utils/Options.cc @@ -21,9 +21,9 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "utils/Options.h" #include "utils/ParseUtils.h" -using namespace Minisat; +using namespace Glucose; -void Minisat::parseOptions(int& argc, char** argv, bool strict) +void Glucose::parseOptions(int& argc, char** argv, bool strict) { int i, j; for (i = j = 1; i < argc; i++){ @@ -54,9 +54,9 @@ void Minisat::parseOptions(int& argc, char** argv, bool strict) } -void Minisat::setUsageHelp (const char* str){ Option::getUsageString() = str; } -void Minisat::setHelpPrefixStr (const char* str){ Option::getHelpPrefixString() = str; } -void Minisat::printUsageAndExit (int argc, char** argv, bool verbose) +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) diff --git a/sources/glucose/utils/Options.h b/utils/Options.h similarity index 99% rename from sources/glucose/utils/Options.h rename to utils/Options.h index 9c1f406..3570f23 100644 --- a/sources/glucose/utils/Options.h +++ b/utils/Options.h @@ -17,8 +17,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_Options_h -#define Minisat_Options_h +#ifndef Glucose_Options_h +#define Glucose_Options_h #include #include @@ -29,7 +29,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "mtl/Vec.h" #include "utils/ParseUtils.h" -namespace Minisat { +namespace Glucose { //================================================================================================== // Top-level option parse/help functions: diff --git a/sources/glucose/utils/ParseUtils.h b/utils/ParseUtils.h similarity index 98% rename from sources/glucose/utils/ParseUtils.h rename to utils/ParseUtils.h index 9dd5c2f..f411086 100644 --- a/sources/glucose/utils/ParseUtils.h +++ b/utils/ParseUtils.h @@ -18,8 +18,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_ParseUtils_h -#define Minisat_ParseUtils_h +#ifndef Glucose_ParseUtils_h +#define Glucose_ParseUtils_h #include #include @@ -27,7 +27,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include -namespace Minisat { +namespace Glucose { //------------------------------------------------------------------------------------------------- // A simple buffered character stream class: diff --git a/sources/glucose/utils/System.cc b/utils/System.cc similarity index 93% rename from sources/glucose/utils/System.cc rename to utils/System.cc index a7cf53f..a516e0b 100644 --- a/sources/glucose/utils/System.cc +++ b/utils/System.cc @@ -25,7 +25,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include #include -using namespace Minisat; +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. @@ -67,14 +67,14 @@ static inline int memReadPeak(void) return peak_kb; } -double Minisat::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); } -double Minisat::memUsedPeak() { +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 Minisat::memUsed(void) { +double Glucose::memUsed(void) { struct rusage ru; getrusage(RUSAGE_SELF, &ru); return (double)ru.ru_maxrss / 1024; } @@ -84,12 +84,12 @@ double MiniSat::memUsedPeak(void) { return memUsed(); } #elif defined(__APPLE__) #include -double Minisat::memUsed(void) { +double Glucose::memUsed(void) { malloc_statistics_t t; malloc_zone_statistics(NULL, &t); return (double)t.max_size_in_use / (1024*1024); } #else -double Minisat::memUsed() { +double Glucose::memUsed() { return 0; } #endif diff --git a/sources/glucose/utils/System.h b/utils/System.h similarity index 92% rename from sources/glucose/utils/System.h rename to utils/System.h index 1758192..4788070 100644 --- a/sources/glucose/utils/System.h +++ b/utils/System.h @@ -18,8 +18,8 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************************************/ -#ifndef Minisat_System_h -#define Minisat_System_h +#ifndef Glucose_System_h +#define Glucose_System_h #if defined(__linux__) #include @@ -29,7 +29,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA //------------------------------------------------------------------------------------------------- -namespace Minisat { +namespace Glucose { static inline double cpuTime(void); // CPU-time in seconds. extern double memUsed(); // Memory in mega bytes (returns 0 for unsupported architectures). @@ -43,14 +43,14 @@ extern double memUsedPeak(); // Peak-memory in mega bytes (returns 0 for #if defined(_MSC_VER) || defined(__MINGW32__) #include -static inline double Minisat::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; } +static inline double Glucose::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; } #else #include #include #include -static inline double Minisat::cpuTime(void) { +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; }