ruby-minisat 1.14.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -21
- data/Gemfile +4 -0
- data/LICENSE +3 -2
- data/README.md +42 -0
- data/Rakefile +1 -48
- data/examples/shikaku.rb +2 -2
- data/ext/minisat/extconf.rb +19 -4
- data/ext/minisat/minisat-wrap.cpp +11 -5
- data/ext/minisat/minisat.c +17 -3
- data/ext/minisat/minisat.h +1 -1
- data/minisat/minisat-2.2.0.tar.gz +0 -0
- data/minisat/{MiniSat_v1.14 → minisat}/LICENSE +2 -1
- data/minisat/minisat/README +24 -0
- data/minisat/minisat/core/Dimacs.h +89 -0
- data/minisat/minisat/core/Main.cc +192 -0
- data/minisat/minisat/core/Solver.cc +923 -0
- data/minisat/minisat/core/Solver.h +373 -0
- data/minisat/minisat/core/SolverTypes.h +407 -0
- data/minisat/minisat/mtl/Alg.h +84 -0
- data/minisat/minisat/mtl/Alloc.h +131 -0
- data/minisat/minisat/mtl/Heap.h +148 -0
- data/minisat/minisat/mtl/IntTypes.h +42 -0
- data/minisat/minisat/mtl/Map.h +193 -0
- data/minisat/minisat/mtl/Queue.h +69 -0
- data/minisat/{MiniSat_v1.14 → minisat/mtl}/Sort.h +14 -47
- data/minisat/minisat/mtl/Vec.h +130 -0
- data/minisat/minisat/mtl/XAlloc.h +45 -0
- data/minisat/minisat/mtl/config.mk +6 -0
- data/minisat/minisat/mtl/template.mk +107 -0
- data/minisat/minisat/simp/Main.cc +211 -0
- data/minisat/minisat/simp/SimpSolver.cc +717 -0
- data/minisat/minisat/simp/SimpSolver.h +197 -0
- data/minisat/minisat/utils/Options.cc +91 -0
- data/minisat/minisat/utils/Options.h +386 -0
- data/minisat/minisat/utils/ParseUtils.h +122 -0
- data/minisat/minisat/utils/System.cc +95 -0
- data/minisat/minisat/utils/System.h +60 -0
- data/ruby-minisat.gemspec +21 -0
- metadata +94 -75
- data/README.rdoc +0 -56
- data/minisat/MiniSat_v1.14.2006-Aug-29.src.zip +0 -0
- data/minisat/MiniSat_v1.14/Global.h +0 -274
- data/minisat/MiniSat_v1.14/Heap.h +0 -100
- data/minisat/MiniSat_v1.14/Main.C +0 -244
- data/minisat/MiniSat_v1.14/Makefile +0 -88
- data/minisat/MiniSat_v1.14/README +0 -30
- data/minisat/MiniSat_v1.14/Solver.C +0 -781
- data/minisat/MiniSat_v1.14/Solver.h +0 -206
- data/minisat/MiniSat_v1.14/Solver.o +0 -0
- data/minisat/MiniSat_v1.14/SolverTypes.h +0 -130
- data/minisat/MiniSat_v1.14/TODO +0 -73
- data/minisat/MiniSat_v1.14/VarOrder.h +0 -96
@@ -0,0 +1,211 @@
|
|
1
|
+
/*****************************************************************************************[Main.cc]
|
2
|
+
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
|
3
|
+
Copyright (c) 2007, Niklas Sorensson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
8
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
12
|
+
substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
15
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
17
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
18
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
|
+
**************************************************************************************************/
|
20
|
+
|
21
|
+
#include <errno.h>
|
22
|
+
|
23
|
+
#include <signal.h>
|
24
|
+
#include <zlib.h>
|
25
|
+
#include <sys/resource.h>
|
26
|
+
|
27
|
+
#include "utils/System.h"
|
28
|
+
#include "utils/ParseUtils.h"
|
29
|
+
#include "utils/Options.h"
|
30
|
+
#include "core/Dimacs.h"
|
31
|
+
#include "simp/SimpSolver.h"
|
32
|
+
|
33
|
+
using namespace Minisat;
|
34
|
+
|
35
|
+
//=================================================================================================
|
36
|
+
|
37
|
+
|
38
|
+
void printStats(Solver& solver)
|
39
|
+
{
|
40
|
+
double cpu_time = cpuTime();
|
41
|
+
double mem_used = memUsedPeak();
|
42
|
+
printf("restarts : %"PRIu64"\n", solver.starts);
|
43
|
+
printf("conflicts : %-12"PRIu64" (%.0f /sec)\n", solver.conflicts , solver.conflicts /cpu_time);
|
44
|
+
printf("decisions : %-12"PRIu64" (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions /cpu_time);
|
45
|
+
printf("propagations : %-12"PRIu64" (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time);
|
46
|
+
printf("conflict literals : %-12"PRIu64" (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals);
|
47
|
+
if (mem_used != 0) printf("Memory used : %.2f MB\n", mem_used);
|
48
|
+
printf("CPU time : %g s\n", cpu_time);
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
static Solver* solver;
|
53
|
+
// Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case
|
54
|
+
// for this feature of the Solver as it may take longer than an immediate call to '_exit()'.
|
55
|
+
static void SIGINT_interrupt(int signum) { solver->interrupt(); }
|
56
|
+
|
57
|
+
// Note that '_exit()' rather than 'exit()' has to be used. The reason is that 'exit()' calls
|
58
|
+
// destructors and may cause deadlocks if a malloc/free function happens to be running (these
|
59
|
+
// functions are guarded by locks for multithreaded use).
|
60
|
+
static void SIGINT_exit(int signum) {
|
61
|
+
printf("\n"); printf("*** INTERRUPTED ***\n");
|
62
|
+
if (solver->verbosity > 0){
|
63
|
+
printStats(*solver);
|
64
|
+
printf("\n"); printf("*** INTERRUPTED ***\n"); }
|
65
|
+
_exit(1); }
|
66
|
+
|
67
|
+
|
68
|
+
//=================================================================================================
|
69
|
+
// Main:
|
70
|
+
|
71
|
+
int main(int argc, char** argv)
|
72
|
+
{
|
73
|
+
try {
|
74
|
+
setUsageHelp("USAGE: %s [options] <input-file> <result-output-file>\n\n where input may be either in plain or gzipped DIMACS.\n");
|
75
|
+
// printf("This is MiniSat 2.0 beta\n");
|
76
|
+
|
77
|
+
#if defined(__linux__)
|
78
|
+
fpu_control_t oldcw, newcw;
|
79
|
+
_FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
|
80
|
+
printf("WARNING: for repeatability, setting FPU to use double precision\n");
|
81
|
+
#endif
|
82
|
+
// Extra options:
|
83
|
+
//
|
84
|
+
IntOption verb ("MAIN", "verb", "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2));
|
85
|
+
BoolOption pre ("MAIN", "pre", "Completely turn on/off any preprocessing.", true);
|
86
|
+
StringOption dimacs ("MAIN", "dimacs", "If given, stop after preprocessing and write the result to this file.");
|
87
|
+
IntOption cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX));
|
88
|
+
IntOption mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX));
|
89
|
+
|
90
|
+
parseOptions(argc, argv, true);
|
91
|
+
|
92
|
+
SimpSolver S;
|
93
|
+
double initial_time = cpuTime();
|
94
|
+
|
95
|
+
if (!pre) S.eliminate(true);
|
96
|
+
|
97
|
+
S.verbosity = verb;
|
98
|
+
|
99
|
+
solver = &S;
|
100
|
+
// Use signal handlers that forcibly quit until the solver will be able to respond to
|
101
|
+
// interrupts:
|
102
|
+
signal(SIGINT, SIGINT_exit);
|
103
|
+
signal(SIGXCPU,SIGINT_exit);
|
104
|
+
|
105
|
+
// Set limit on CPU-time:
|
106
|
+
if (cpu_lim != INT32_MAX){
|
107
|
+
rlimit rl;
|
108
|
+
getrlimit(RLIMIT_CPU, &rl);
|
109
|
+
if (rl.rlim_max == RLIM_INFINITY || (rlim_t)cpu_lim < rl.rlim_max){
|
110
|
+
rl.rlim_cur = cpu_lim;
|
111
|
+
if (setrlimit(RLIMIT_CPU, &rl) == -1)
|
112
|
+
printf("WARNING! Could not set resource limit: CPU-time.\n");
|
113
|
+
} }
|
114
|
+
|
115
|
+
// Set limit on virtual memory:
|
116
|
+
if (mem_lim != INT32_MAX){
|
117
|
+
rlim_t new_mem_lim = (rlim_t)mem_lim * 1024*1024;
|
118
|
+
rlimit rl;
|
119
|
+
getrlimit(RLIMIT_AS, &rl);
|
120
|
+
if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){
|
121
|
+
rl.rlim_cur = new_mem_lim;
|
122
|
+
if (setrlimit(RLIMIT_AS, &rl) == -1)
|
123
|
+
printf("WARNING! Could not set resource limit: Virtual memory.\n");
|
124
|
+
} }
|
125
|
+
|
126
|
+
if (argc == 1)
|
127
|
+
printf("Reading from standard input... Use '--help' for help.\n");
|
128
|
+
|
129
|
+
gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
|
130
|
+
if (in == NULL)
|
131
|
+
printf("ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]), exit(1);
|
132
|
+
|
133
|
+
if (S.verbosity > 0){
|
134
|
+
printf("============================[ Problem Statistics ]=============================\n");
|
135
|
+
printf("| |\n"); }
|
136
|
+
|
137
|
+
parse_DIMACS(in, S);
|
138
|
+
gzclose(in);
|
139
|
+
FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;
|
140
|
+
|
141
|
+
if (S.verbosity > 0){
|
142
|
+
printf("| Number of variables: %12d |\n", S.nVars());
|
143
|
+
printf("| Number of clauses: %12d |\n", S.nClauses()); }
|
144
|
+
|
145
|
+
double parsed_time = cpuTime();
|
146
|
+
if (S.verbosity > 0)
|
147
|
+
printf("| Parse time: %12.2f s |\n", parsed_time - initial_time);
|
148
|
+
|
149
|
+
// Change to signal-handlers that will only notify the solver and allow it to terminate
|
150
|
+
// voluntarily:
|
151
|
+
signal(SIGINT, SIGINT_interrupt);
|
152
|
+
signal(SIGXCPU,SIGINT_interrupt);
|
153
|
+
|
154
|
+
S.eliminate(true);
|
155
|
+
double simplified_time = cpuTime();
|
156
|
+
if (S.verbosity > 0){
|
157
|
+
printf("| Simplification time: %12.2f s |\n", simplified_time - parsed_time);
|
158
|
+
printf("| |\n"); }
|
159
|
+
|
160
|
+
if (!S.okay()){
|
161
|
+
if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res);
|
162
|
+
if (S.verbosity > 0){
|
163
|
+
printf("===============================================================================\n");
|
164
|
+
printf("Solved by simplification\n");
|
165
|
+
printStats(S);
|
166
|
+
printf("\n"); }
|
167
|
+
printf("UNSATISFIABLE\n");
|
168
|
+
exit(20);
|
169
|
+
}
|
170
|
+
|
171
|
+
if (dimacs){
|
172
|
+
if (S.verbosity > 0)
|
173
|
+
printf("==============================[ Writing DIMACS ]===============================\n");
|
174
|
+
S.toDimacs((const char*)dimacs);
|
175
|
+
if (S.verbosity > 0)
|
176
|
+
printStats(S);
|
177
|
+
exit(0);
|
178
|
+
}
|
179
|
+
|
180
|
+
vec<Lit> dummy;
|
181
|
+
lbool ret = S.solveLimited(dummy);
|
182
|
+
|
183
|
+
if (S.verbosity > 0){
|
184
|
+
printStats(S);
|
185
|
+
printf("\n"); }
|
186
|
+
printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n");
|
187
|
+
if (res != NULL){
|
188
|
+
if (ret == l_True){
|
189
|
+
fprintf(res, "SAT\n");
|
190
|
+
for (int i = 0; i < S.nVars(); i++)
|
191
|
+
if (S.model[i] != l_Undef)
|
192
|
+
fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1);
|
193
|
+
fprintf(res, " 0\n");
|
194
|
+
}else if (ret == l_False)
|
195
|
+
fprintf(res, "UNSAT\n");
|
196
|
+
else
|
197
|
+
fprintf(res, "INDET\n");
|
198
|
+
fclose(res);
|
199
|
+
}
|
200
|
+
|
201
|
+
#ifdef NDEBUG
|
202
|
+
exit(ret == l_True ? 10 : ret == l_False ? 20 : 0); // (faster than "return", which will invoke the destructor for 'Solver')
|
203
|
+
#else
|
204
|
+
return (ret == l_True ? 10 : ret == l_False ? 20 : 0);
|
205
|
+
#endif
|
206
|
+
} catch (OutOfMemoryException&){
|
207
|
+
printf("===============================================================================\n");
|
208
|
+
printf("INDETERMINATE\n");
|
209
|
+
exit(0);
|
210
|
+
}
|
211
|
+
}
|
@@ -0,0 +1,717 @@
|
|
1
|
+
/***********************************************************************************[SimpSolver.cc]
|
2
|
+
Copyright (c) 2006, Niklas Een, Niklas Sorensson
|
3
|
+
Copyright (c) 2007-2010, Niklas Sorensson
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
8
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
12
|
+
substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
15
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
17
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
18
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
|
+
**************************************************************************************************/
|
20
|
+
|
21
|
+
#include "mtl/Sort.h"
|
22
|
+
#include "simp/SimpSolver.h"
|
23
|
+
#include "utils/System.h"
|
24
|
+
|
25
|
+
using namespace Minisat;
|
26
|
+
|
27
|
+
//=================================================================================================
|
28
|
+
// Options:
|
29
|
+
|
30
|
+
|
31
|
+
static const char* _cat = "SIMP";
|
32
|
+
|
33
|
+
static BoolOption opt_use_asymm (_cat, "asymm", "Shrink clauses by asymmetric branching.", false);
|
34
|
+
static BoolOption opt_use_rcheck (_cat, "rcheck", "Check if a clause is already implied. (costly)", false);
|
35
|
+
static BoolOption opt_use_elim (_cat, "elim", "Perform variable elimination.", true);
|
36
|
+
static IntOption opt_grow (_cat, "grow", "Allow a variable elimination step to grow by a number of clauses.", 0);
|
37
|
+
static IntOption opt_clause_lim (_cat, "cl-lim", "Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20, IntRange(-1, INT32_MAX));
|
38
|
+
static IntOption opt_subsumption_lim (_cat, "sub-lim", "Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX));
|
39
|
+
static DoubleOption opt_simp_garbage_frac(_cat, "simp-gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered during simplification.", 0.5, DoubleRange(0, false, HUGE_VAL, false));
|
40
|
+
|
41
|
+
|
42
|
+
//=================================================================================================
|
43
|
+
// Constructor/Destructor:
|
44
|
+
|
45
|
+
|
46
|
+
SimpSolver::SimpSolver() :
|
47
|
+
grow (opt_grow)
|
48
|
+
, clause_lim (opt_clause_lim)
|
49
|
+
, subsumption_lim (opt_subsumption_lim)
|
50
|
+
, simp_garbage_frac (opt_simp_garbage_frac)
|
51
|
+
, use_asymm (opt_use_asymm)
|
52
|
+
, use_rcheck (opt_use_rcheck)
|
53
|
+
, use_elim (opt_use_elim)
|
54
|
+
, merges (0)
|
55
|
+
, asymm_lits (0)
|
56
|
+
, eliminated_vars (0)
|
57
|
+
, elimorder (1)
|
58
|
+
, use_simplification (true)
|
59
|
+
, occurs (ClauseDeleted(ca))
|
60
|
+
, elim_heap (ElimLt(n_occ))
|
61
|
+
, bwdsub_assigns (0)
|
62
|
+
, n_touched (0)
|
63
|
+
{
|
64
|
+
vec<Lit> dummy(1,lit_Undef);
|
65
|
+
ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
|
66
|
+
bwdsub_tmpunit = ca.alloc(dummy);
|
67
|
+
remove_satisfied = false;
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
SimpSolver::~SimpSolver()
|
72
|
+
{
|
73
|
+
}
|
74
|
+
|
75
|
+
|
76
|
+
Var SimpSolver::newVar(bool sign, bool dvar) {
|
77
|
+
Var v = Solver::newVar(sign, dvar);
|
78
|
+
|
79
|
+
frozen .push((char)false);
|
80
|
+
eliminated.push((char)false);
|
81
|
+
|
82
|
+
if (use_simplification){
|
83
|
+
n_occ .push(0);
|
84
|
+
n_occ .push(0);
|
85
|
+
occurs .init(v);
|
86
|
+
touched .push(0);
|
87
|
+
elim_heap .insert(v);
|
88
|
+
}
|
89
|
+
return v; }
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
lbool SimpSolver::solve_(bool do_simp, bool turn_off_simp)
|
94
|
+
{
|
95
|
+
vec<Var> extra_frozen;
|
96
|
+
lbool result = l_True;
|
97
|
+
|
98
|
+
do_simp &= use_simplification;
|
99
|
+
|
100
|
+
if (do_simp){
|
101
|
+
// Assumptions must be temporarily frozen to run variable elimination:
|
102
|
+
for (int i = 0; i < assumptions.size(); i++){
|
103
|
+
Var v = var(assumptions[i]);
|
104
|
+
|
105
|
+
// If an assumption has been eliminated, remember it.
|
106
|
+
assert(!isEliminated(v));
|
107
|
+
|
108
|
+
if (!frozen[v]){
|
109
|
+
// Freeze and store.
|
110
|
+
setFrozen(v, true);
|
111
|
+
extra_frozen.push(v);
|
112
|
+
} }
|
113
|
+
|
114
|
+
result = lbool(eliminate(turn_off_simp));
|
115
|
+
}
|
116
|
+
|
117
|
+
if (result == l_True)
|
118
|
+
result = Solver::solve_();
|
119
|
+
else if (verbosity >= 1)
|
120
|
+
printf("===============================================================================\n");
|
121
|
+
|
122
|
+
if (result == l_True)
|
123
|
+
extendModel();
|
124
|
+
|
125
|
+
if (do_simp)
|
126
|
+
// Unfreeze the assumptions that were frozen:
|
127
|
+
for (int i = 0; i < extra_frozen.size(); i++)
|
128
|
+
setFrozen(extra_frozen[i], false);
|
129
|
+
|
130
|
+
return result;
|
131
|
+
}
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
bool SimpSolver::addClause_(vec<Lit>& ps)
|
136
|
+
{
|
137
|
+
#ifndef NDEBUG
|
138
|
+
for (int i = 0; i < ps.size(); i++)
|
139
|
+
assert(!isEliminated(var(ps[i])));
|
140
|
+
#endif
|
141
|
+
|
142
|
+
int nclauses = clauses.size();
|
143
|
+
|
144
|
+
if (use_rcheck && implied(ps))
|
145
|
+
return true;
|
146
|
+
|
147
|
+
if (!Solver::addClause_(ps))
|
148
|
+
return false;
|
149
|
+
|
150
|
+
if (use_simplification && clauses.size() == nclauses + 1){
|
151
|
+
CRef cr = clauses.last();
|
152
|
+
const Clause& c = ca[cr];
|
153
|
+
|
154
|
+
// NOTE: the clause is added to the queue immediately and then
|
155
|
+
// again during 'gatherTouchedClauses()'. If nothing happens
|
156
|
+
// in between, it will only be checked once. Otherwise, it may
|
157
|
+
// be checked twice unnecessarily. This is an unfortunate
|
158
|
+
// consequence of how backward subsumption is used to mimic
|
159
|
+
// forward subsumption.
|
160
|
+
subsumption_queue.insert(cr);
|
161
|
+
for (int i = 0; i < c.size(); i++){
|
162
|
+
occurs[var(c[i])].push(cr);
|
163
|
+
n_occ[toInt(c[i])]++;
|
164
|
+
touched[var(c[i])] = 1;
|
165
|
+
n_touched++;
|
166
|
+
if (elim_heap.inHeap(var(c[i])))
|
167
|
+
elim_heap.increase(var(c[i]));
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
171
|
+
return true;
|
172
|
+
}
|
173
|
+
|
174
|
+
|
175
|
+
void SimpSolver::removeClause(CRef cr)
|
176
|
+
{
|
177
|
+
const Clause& c = ca[cr];
|
178
|
+
|
179
|
+
if (use_simplification)
|
180
|
+
for (int i = 0; i < c.size(); i++){
|
181
|
+
n_occ[toInt(c[i])]--;
|
182
|
+
updateElimHeap(var(c[i]));
|
183
|
+
occurs.smudge(var(c[i]));
|
184
|
+
}
|
185
|
+
|
186
|
+
Solver::removeClause(cr);
|
187
|
+
}
|
188
|
+
|
189
|
+
|
190
|
+
bool SimpSolver::strengthenClause(CRef cr, Lit l)
|
191
|
+
{
|
192
|
+
Clause& c = ca[cr];
|
193
|
+
assert(decisionLevel() == 0);
|
194
|
+
assert(use_simplification);
|
195
|
+
|
196
|
+
// FIX: this is too inefficient but would be nice to have (properly implemented)
|
197
|
+
// if (!find(subsumption_queue, &c))
|
198
|
+
subsumption_queue.insert(cr);
|
199
|
+
|
200
|
+
if (c.size() == 2){
|
201
|
+
removeClause(cr);
|
202
|
+
c.strengthen(l);
|
203
|
+
}else{
|
204
|
+
detachClause(cr, true);
|
205
|
+
c.strengthen(l);
|
206
|
+
attachClause(cr);
|
207
|
+
remove(occurs[var(l)], cr);
|
208
|
+
n_occ[toInt(l)]--;
|
209
|
+
updateElimHeap(var(l));
|
210
|
+
}
|
211
|
+
|
212
|
+
return c.size() == 1 ? enqueue(c[0]) && propagate() == CRef_Undef : true;
|
213
|
+
}
|
214
|
+
|
215
|
+
|
216
|
+
// Returns FALSE if clause is always satisfied ('out_clause' should not be used).
|
217
|
+
bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
|
218
|
+
{
|
219
|
+
merges++;
|
220
|
+
out_clause.clear();
|
221
|
+
|
222
|
+
bool ps_smallest = _ps.size() < _qs.size();
|
223
|
+
const Clause& ps = ps_smallest ? _qs : _ps;
|
224
|
+
const Clause& qs = ps_smallest ? _ps : _qs;
|
225
|
+
|
226
|
+
for (int i = 0; i < qs.size(); i++){
|
227
|
+
if (var(qs[i]) != v){
|
228
|
+
for (int j = 0; j < ps.size(); j++)
|
229
|
+
if (var(ps[j]) == var(qs[i]))
|
230
|
+
if (ps[j] == ~qs[i])
|
231
|
+
return false;
|
232
|
+
else
|
233
|
+
goto next;
|
234
|
+
out_clause.push(qs[i]);
|
235
|
+
}
|
236
|
+
next:;
|
237
|
+
}
|
238
|
+
|
239
|
+
for (int i = 0; i < ps.size(); i++)
|
240
|
+
if (var(ps[i]) != v)
|
241
|
+
out_clause.push(ps[i]);
|
242
|
+
|
243
|
+
return true;
|
244
|
+
}
|
245
|
+
|
246
|
+
|
247
|
+
// Returns FALSE if clause is always satisfied.
|
248
|
+
bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size)
|
249
|
+
{
|
250
|
+
merges++;
|
251
|
+
|
252
|
+
bool ps_smallest = _ps.size() < _qs.size();
|
253
|
+
const Clause& ps = ps_smallest ? _qs : _ps;
|
254
|
+
const Clause& qs = ps_smallest ? _ps : _qs;
|
255
|
+
const Lit* __ps = (const Lit*)ps;
|
256
|
+
const Lit* __qs = (const Lit*)qs;
|
257
|
+
|
258
|
+
size = ps.size()-1;
|
259
|
+
|
260
|
+
for (int i = 0; i < qs.size(); i++){
|
261
|
+
if (var(__qs[i]) != v){
|
262
|
+
for (int j = 0; j < ps.size(); j++)
|
263
|
+
if (var(__ps[j]) == var(__qs[i]))
|
264
|
+
if (__ps[j] == ~__qs[i])
|
265
|
+
return false;
|
266
|
+
else
|
267
|
+
goto next;
|
268
|
+
size++;
|
269
|
+
}
|
270
|
+
next:;
|
271
|
+
}
|
272
|
+
|
273
|
+
return true;
|
274
|
+
}
|
275
|
+
|
276
|
+
|
277
|
+
void SimpSolver::gatherTouchedClauses()
|
278
|
+
{
|
279
|
+
if (n_touched == 0) return;
|
280
|
+
|
281
|
+
int i,j;
|
282
|
+
for (i = j = 0; i < subsumption_queue.size(); i++)
|
283
|
+
if (ca[subsumption_queue[i]].mark() == 0)
|
284
|
+
ca[subsumption_queue[i]].mark(2);
|
285
|
+
|
286
|
+
for (i = 0; i < touched.size(); i++)
|
287
|
+
if (touched[i]){
|
288
|
+
const vec<CRef>& cs = occurs.lookup(i);
|
289
|
+
for (j = 0; j < cs.size(); j++)
|
290
|
+
if (ca[cs[j]].mark() == 0){
|
291
|
+
subsumption_queue.insert(cs[j]);
|
292
|
+
ca[cs[j]].mark(2);
|
293
|
+
}
|
294
|
+
touched[i] = 0;
|
295
|
+
}
|
296
|
+
|
297
|
+
for (i = 0; i < subsumption_queue.size(); i++)
|
298
|
+
if (ca[subsumption_queue[i]].mark() == 2)
|
299
|
+
ca[subsumption_queue[i]].mark(0);
|
300
|
+
|
301
|
+
n_touched = 0;
|
302
|
+
}
|
303
|
+
|
304
|
+
|
305
|
+
bool SimpSolver::implied(const vec<Lit>& c)
|
306
|
+
{
|
307
|
+
assert(decisionLevel() == 0);
|
308
|
+
|
309
|
+
trail_lim.push(trail.size());
|
310
|
+
for (int i = 0; i < c.size(); i++)
|
311
|
+
if (value(c[i]) == l_True){
|
312
|
+
cancelUntil(0);
|
313
|
+
return false;
|
314
|
+
}else if (value(c[i]) != l_False){
|
315
|
+
assert(value(c[i]) == l_Undef);
|
316
|
+
uncheckedEnqueue(~c[i]);
|
317
|
+
}
|
318
|
+
|
319
|
+
bool result = propagate() != CRef_Undef;
|
320
|
+
cancelUntil(0);
|
321
|
+
return result;
|
322
|
+
}
|
323
|
+
|
324
|
+
|
325
|
+
// Backward subsumption + backward subsumption resolution
|
326
|
+
bool SimpSolver::backwardSubsumptionCheck(bool verbose)
|
327
|
+
{
|
328
|
+
int cnt = 0;
|
329
|
+
int subsumed = 0;
|
330
|
+
int deleted_literals = 0;
|
331
|
+
assert(decisionLevel() == 0);
|
332
|
+
|
333
|
+
while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){
|
334
|
+
|
335
|
+
// Empty subsumption queue and return immediately on user-interrupt:
|
336
|
+
if (asynch_interrupt){
|
337
|
+
subsumption_queue.clear();
|
338
|
+
bwdsub_assigns = trail.size();
|
339
|
+
break; }
|
340
|
+
|
341
|
+
// Check top-level assignments by creating a dummy clause and placing it in the queue:
|
342
|
+
if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){
|
343
|
+
Lit l = trail[bwdsub_assigns++];
|
344
|
+
ca[bwdsub_tmpunit][0] = l;
|
345
|
+
ca[bwdsub_tmpunit].calcAbstraction();
|
346
|
+
subsumption_queue.insert(bwdsub_tmpunit); }
|
347
|
+
|
348
|
+
CRef cr = subsumption_queue.peek(); subsumption_queue.pop();
|
349
|
+
Clause& c = ca[cr];
|
350
|
+
|
351
|
+
if (c.mark()) continue;
|
352
|
+
|
353
|
+
if (verbose && verbosity >= 2 && cnt++ % 1000 == 0)
|
354
|
+
printf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals);
|
355
|
+
|
356
|
+
assert(c.size() > 1 || value(c[0]) == l_True); // Unit-clauses should have been propagated before this point.
|
357
|
+
|
358
|
+
// Find best variable to scan:
|
359
|
+
Var best = var(c[0]);
|
360
|
+
for (int i = 1; i < c.size(); i++)
|
361
|
+
if (occurs[var(c[i])].size() < occurs[best].size())
|
362
|
+
best = var(c[i]);
|
363
|
+
|
364
|
+
// Search all candidates:
|
365
|
+
vec<CRef>& _cs = occurs.lookup(best);
|
366
|
+
CRef* cs = (CRef*)_cs;
|
367
|
+
|
368
|
+
for (int j = 0; j < _cs.size(); j++)
|
369
|
+
if (c.mark())
|
370
|
+
break;
|
371
|
+
else if (!ca[cs[j]].mark() && cs[j] != cr && (subsumption_lim == -1 || ca[cs[j]].size() < subsumption_lim)){
|
372
|
+
Lit l = c.subsumes(ca[cs[j]]);
|
373
|
+
|
374
|
+
if (l == lit_Undef)
|
375
|
+
subsumed++, removeClause(cs[j]);
|
376
|
+
else if (l != lit_Error){
|
377
|
+
deleted_literals++;
|
378
|
+
|
379
|
+
if (!strengthenClause(cs[j], ~l))
|
380
|
+
return false;
|
381
|
+
|
382
|
+
// Did current candidate get deleted from cs? Then check candidate at index j again:
|
383
|
+
if (var(l) == best)
|
384
|
+
j--;
|
385
|
+
}
|
386
|
+
}
|
387
|
+
}
|
388
|
+
|
389
|
+
return true;
|
390
|
+
}
|
391
|
+
|
392
|
+
|
393
|
+
bool SimpSolver::asymm(Var v, CRef cr)
|
394
|
+
{
|
395
|
+
Clause& c = ca[cr];
|
396
|
+
assert(decisionLevel() == 0);
|
397
|
+
|
398
|
+
if (c.mark() || satisfied(c)) return true;
|
399
|
+
|
400
|
+
trail_lim.push(trail.size());
|
401
|
+
Lit l = lit_Undef;
|
402
|
+
for (int i = 0; i < c.size(); i++)
|
403
|
+
if (var(c[i]) != v && value(c[i]) != l_False)
|
404
|
+
uncheckedEnqueue(~c[i]);
|
405
|
+
else
|
406
|
+
l = c[i];
|
407
|
+
|
408
|
+
if (propagate() != CRef_Undef){
|
409
|
+
cancelUntil(0);
|
410
|
+
asymm_lits++;
|
411
|
+
if (!strengthenClause(cr, l))
|
412
|
+
return false;
|
413
|
+
}else
|
414
|
+
cancelUntil(0);
|
415
|
+
|
416
|
+
return true;
|
417
|
+
}
|
418
|
+
|
419
|
+
|
420
|
+
bool SimpSolver::asymmVar(Var v)
|
421
|
+
{
|
422
|
+
assert(use_simplification);
|
423
|
+
|
424
|
+
const vec<CRef>& cls = occurs.lookup(v);
|
425
|
+
|
426
|
+
if (value(v) != l_Undef || cls.size() == 0)
|
427
|
+
return true;
|
428
|
+
|
429
|
+
for (int i = 0; i < cls.size(); i++)
|
430
|
+
if (!asymm(v, cls[i]))
|
431
|
+
return false;
|
432
|
+
|
433
|
+
return backwardSubsumptionCheck();
|
434
|
+
}
|
435
|
+
|
436
|
+
|
437
|
+
static void mkElimClause(vec<uint32_t>& elimclauses, Lit x)
|
438
|
+
{
|
439
|
+
elimclauses.push(toInt(x));
|
440
|
+
elimclauses.push(1);
|
441
|
+
}
|
442
|
+
|
443
|
+
|
444
|
+
static void mkElimClause(vec<uint32_t>& elimclauses, Var v, Clause& c)
|
445
|
+
{
|
446
|
+
int first = elimclauses.size();
|
447
|
+
int v_pos = -1;
|
448
|
+
|
449
|
+
// Copy clause to elimclauses-vector. Remember position where the
|
450
|
+
// variable 'v' occurs:
|
451
|
+
for (int i = 0; i < c.size(); i++){
|
452
|
+
elimclauses.push(toInt(c[i]));
|
453
|
+
if (var(c[i]) == v)
|
454
|
+
v_pos = i + first;
|
455
|
+
}
|
456
|
+
assert(v_pos != -1);
|
457
|
+
|
458
|
+
// Swap the first literal with the 'v' literal, so that the literal
|
459
|
+
// containing 'v' will occur first in the clause:
|
460
|
+
uint32_t tmp = elimclauses[v_pos];
|
461
|
+
elimclauses[v_pos] = elimclauses[first];
|
462
|
+
elimclauses[first] = tmp;
|
463
|
+
|
464
|
+
// Store the length of the clause last:
|
465
|
+
elimclauses.push(c.size());
|
466
|
+
}
|
467
|
+
|
468
|
+
|
469
|
+
|
470
|
+
bool SimpSolver::eliminateVar(Var v)
|
471
|
+
{
|
472
|
+
assert(!frozen[v]);
|
473
|
+
assert(!isEliminated(v));
|
474
|
+
assert(value(v) == l_Undef);
|
475
|
+
|
476
|
+
// Split the occurrences into positive and negative:
|
477
|
+
//
|
478
|
+
const vec<CRef>& cls = occurs.lookup(v);
|
479
|
+
vec<CRef> pos, neg;
|
480
|
+
for (int i = 0; i < cls.size(); i++)
|
481
|
+
(find(ca[cls[i]], mkLit(v)) ? pos : neg).push(cls[i]);
|
482
|
+
|
483
|
+
// Check wether the increase in number of clauses stays within the allowed ('grow'). Moreover, no
|
484
|
+
// clause must exceed the limit on the maximal clause size (if it is set):
|
485
|
+
//
|
486
|
+
int cnt = 0;
|
487
|
+
int clause_size = 0;
|
488
|
+
|
489
|
+
for (int i = 0; i < pos.size(); i++)
|
490
|
+
for (int j = 0; j < neg.size(); j++)
|
491
|
+
if (merge(ca[pos[i]], ca[neg[j]], v, clause_size) &&
|
492
|
+
(++cnt > cls.size() + grow || (clause_lim != -1 && clause_size > clause_lim)))
|
493
|
+
return true;
|
494
|
+
|
495
|
+
// Delete and store old clauses:
|
496
|
+
eliminated[v] = true;
|
497
|
+
setDecisionVar(v, false);
|
498
|
+
eliminated_vars++;
|
499
|
+
|
500
|
+
if (pos.size() > neg.size()){
|
501
|
+
for (int i = 0; i < neg.size(); i++)
|
502
|
+
mkElimClause(elimclauses, v, ca[neg[i]]);
|
503
|
+
mkElimClause(elimclauses, mkLit(v));
|
504
|
+
}else{
|
505
|
+
for (int i = 0; i < pos.size(); i++)
|
506
|
+
mkElimClause(elimclauses, v, ca[pos[i]]);
|
507
|
+
mkElimClause(elimclauses, ~mkLit(v));
|
508
|
+
}
|
509
|
+
|
510
|
+
for (int i = 0; i < cls.size(); i++)
|
511
|
+
removeClause(cls[i]);
|
512
|
+
|
513
|
+
// Produce clauses in cross product:
|
514
|
+
vec<Lit>& resolvent = add_tmp;
|
515
|
+
for (int i = 0; i < pos.size(); i++)
|
516
|
+
for (int j = 0; j < neg.size(); j++)
|
517
|
+
if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent))
|
518
|
+
return false;
|
519
|
+
|
520
|
+
// Free occurs list for this variable:
|
521
|
+
occurs[v].clear(true);
|
522
|
+
|
523
|
+
// Free watchers lists for this variable, if possible:
|
524
|
+
if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true);
|
525
|
+
if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true);
|
526
|
+
|
527
|
+
return backwardSubsumptionCheck();
|
528
|
+
}
|
529
|
+
|
530
|
+
|
531
|
+
bool SimpSolver::substitute(Var v, Lit x)
|
532
|
+
{
|
533
|
+
assert(!frozen[v]);
|
534
|
+
assert(!isEliminated(v));
|
535
|
+
assert(value(v) == l_Undef);
|
536
|
+
|
537
|
+
if (!ok) return false;
|
538
|
+
|
539
|
+
eliminated[v] = true;
|
540
|
+
setDecisionVar(v, false);
|
541
|
+
const vec<CRef>& cls = occurs.lookup(v);
|
542
|
+
|
543
|
+
vec<Lit>& subst_clause = add_tmp;
|
544
|
+
for (int i = 0; i < cls.size(); i++){
|
545
|
+
Clause& c = ca[cls[i]];
|
546
|
+
|
547
|
+
subst_clause.clear();
|
548
|
+
for (int j = 0; j < c.size(); j++){
|
549
|
+
Lit p = c[j];
|
550
|
+
subst_clause.push(var(p) == v ? x ^ sign(p) : p);
|
551
|
+
}
|
552
|
+
|
553
|
+
removeClause(cls[i]);
|
554
|
+
|
555
|
+
if (!addClause_(subst_clause))
|
556
|
+
return ok = false;
|
557
|
+
}
|
558
|
+
|
559
|
+
return true;
|
560
|
+
}
|
561
|
+
|
562
|
+
|
563
|
+
void SimpSolver::extendModel()
|
564
|
+
{
|
565
|
+
int i, j;
|
566
|
+
Lit x;
|
567
|
+
|
568
|
+
for (i = elimclauses.size()-1; i > 0; i -= j){
|
569
|
+
for (j = elimclauses[i--]; j > 1; j--, i--)
|
570
|
+
if (modelValue(toLit(elimclauses[i])) != l_False)
|
571
|
+
goto next;
|
572
|
+
|
573
|
+
x = toLit(elimclauses[i]);
|
574
|
+
model[var(x)] = lbool(!sign(x));
|
575
|
+
next:;
|
576
|
+
}
|
577
|
+
}
|
578
|
+
|
579
|
+
|
580
|
+
bool SimpSolver::eliminate(bool turn_off_elim)
|
581
|
+
{
|
582
|
+
if (!simplify())
|
583
|
+
return false;
|
584
|
+
else if (!use_simplification)
|
585
|
+
return true;
|
586
|
+
|
587
|
+
// Main simplification loop:
|
588
|
+
//
|
589
|
+
while (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0){
|
590
|
+
|
591
|
+
gatherTouchedClauses();
|
592
|
+
// printf(" ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns);
|
593
|
+
if ((subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()) &&
|
594
|
+
!backwardSubsumptionCheck(true)){
|
595
|
+
ok = false; goto cleanup; }
|
596
|
+
|
597
|
+
// Empty elim_heap and return immediately on user-interrupt:
|
598
|
+
if (asynch_interrupt){
|
599
|
+
assert(bwdsub_assigns == trail.size());
|
600
|
+
assert(subsumption_queue.size() == 0);
|
601
|
+
assert(n_touched == 0);
|
602
|
+
elim_heap.clear();
|
603
|
+
goto cleanup; }
|
604
|
+
|
605
|
+
// printf(" ## (time = %6.2f s) ELIM: vars = %d\n", cpuTime(), elim_heap.size());
|
606
|
+
for (int cnt = 0; !elim_heap.empty(); cnt++){
|
607
|
+
Var elim = elim_heap.removeMin();
|
608
|
+
|
609
|
+
if (asynch_interrupt) break;
|
610
|
+
|
611
|
+
if (isEliminated(elim) || value(elim) != l_Undef) continue;
|
612
|
+
|
613
|
+
if (verbosity >= 2 && cnt % 100 == 0)
|
614
|
+
printf("elimination left: %10d\r", elim_heap.size());
|
615
|
+
|
616
|
+
if (use_asymm){
|
617
|
+
// Temporarily freeze variable. Otherwise, it would immediately end up on the queue again:
|
618
|
+
bool was_frozen = frozen[elim];
|
619
|
+
frozen[elim] = true;
|
620
|
+
if (!asymmVar(elim)){
|
621
|
+
ok = false; goto cleanup; }
|
622
|
+
frozen[elim] = was_frozen; }
|
623
|
+
|
624
|
+
// At this point, the variable may have been set by assymetric branching, so check it
|
625
|
+
// again. Also, don't eliminate frozen variables:
|
626
|
+
if (use_elim && value(elim) == l_Undef && !frozen[elim] && !eliminateVar(elim)){
|
627
|
+
ok = false; goto cleanup; }
|
628
|
+
|
629
|
+
checkGarbage(simp_garbage_frac);
|
630
|
+
}
|
631
|
+
|
632
|
+
assert(subsumption_queue.size() == 0);
|
633
|
+
}
|
634
|
+
cleanup:
|
635
|
+
|
636
|
+
// If no more simplification is needed, free all simplification-related data structures:
|
637
|
+
if (turn_off_elim){
|
638
|
+
touched .clear(true);
|
639
|
+
occurs .clear(true);
|
640
|
+
n_occ .clear(true);
|
641
|
+
elim_heap.clear(true);
|
642
|
+
subsumption_queue.clear(true);
|
643
|
+
|
644
|
+
use_simplification = false;
|
645
|
+
remove_satisfied = true;
|
646
|
+
ca.extra_clause_field = false;
|
647
|
+
|
648
|
+
// Force full cleanup (this is safe and desirable since it only happens once):
|
649
|
+
rebuildOrderHeap();
|
650
|
+
garbageCollect();
|
651
|
+
}else{
|
652
|
+
// Cheaper cleanup:
|
653
|
+
cleanUpClauses(); // TODO: can we make 'cleanUpClauses()' not be linear in the problem size somehow?
|
654
|
+
checkGarbage();
|
655
|
+
}
|
656
|
+
|
657
|
+
if (verbosity >= 1 && elimclauses.size() > 0)
|
658
|
+
printf("| Eliminated clauses: %10.2f Mb |\n",
|
659
|
+
double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024));
|
660
|
+
|
661
|
+
return ok;
|
662
|
+
}
|
663
|
+
|
664
|
+
|
665
|
+
void SimpSolver::cleanUpClauses()
|
666
|
+
{
|
667
|
+
occurs.cleanAll();
|
668
|
+
int i,j;
|
669
|
+
for (i = j = 0; i < clauses.size(); i++)
|
670
|
+
if (ca[clauses[i]].mark() == 0)
|
671
|
+
clauses[j++] = clauses[i];
|
672
|
+
clauses.shrink(i - j);
|
673
|
+
}
|
674
|
+
|
675
|
+
|
676
|
+
//=================================================================================================
|
677
|
+
// Garbage Collection methods:
|
678
|
+
|
679
|
+
|
680
|
+
void SimpSolver::relocAll(ClauseAllocator& to)
|
681
|
+
{
|
682
|
+
if (!use_simplification) return;
|
683
|
+
|
684
|
+
// All occurs lists:
|
685
|
+
//
|
686
|
+
for (int i = 0; i < nVars(); i++){
|
687
|
+
vec<CRef>& cs = occurs[i];
|
688
|
+
for (int j = 0; j < cs.size(); j++)
|
689
|
+
ca.reloc(cs[j], to);
|
690
|
+
}
|
691
|
+
|
692
|
+
// Subsumption queue:
|
693
|
+
//
|
694
|
+
for (int i = 0; i < subsumption_queue.size(); i++)
|
695
|
+
ca.reloc(subsumption_queue[i], to);
|
696
|
+
|
697
|
+
// Temporary clause:
|
698
|
+
//
|
699
|
+
ca.reloc(bwdsub_tmpunit, to);
|
700
|
+
}
|
701
|
+
|
702
|
+
|
703
|
+
void SimpSolver::garbageCollect()
|
704
|
+
{
|
705
|
+
// Initialize the next region to a size corresponding to the estimated utilization degree. This
|
706
|
+
// is not precise but should avoid some unnecessary reallocations for the new region:
|
707
|
+
ClauseAllocator to(ca.size() - ca.wasted());
|
708
|
+
|
709
|
+
cleanUpClauses();
|
710
|
+
to.extra_clause_field = ca.extra_clause_field; // NOTE: this is important to keep (or lose) the extra fields.
|
711
|
+
relocAll(to);
|
712
|
+
Solver::relocAll(to);
|
713
|
+
if (verbosity >= 2)
|
714
|
+
printf("| Garbage collection: %12d bytes => %12d bytes |\n",
|
715
|
+
ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
|
716
|
+
to.moveTo(ca);
|
717
|
+
}
|