cadical 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +26 -0
- data/README.md +101 -0
- data/ext/cadical/cadical/LICENSE +28 -0
- data/ext/cadical/cadical/README.md +65 -0
- data/ext/cadical/cadical/VERSION +1 -0
- data/ext/cadical/cadical/src/analyze.cpp +1360 -0
- data/ext/cadical/cadical/src/arena.cpp +30 -0
- data/ext/cadical/cadical/src/arena.hpp +105 -0
- data/ext/cadical/cadical/src/assume.cpp +616 -0
- data/ext/cadical/cadical/src/averages.cpp +34 -0
- data/ext/cadical/cadical/src/averages.hpp +37 -0
- data/ext/cadical/cadical/src/backbone.cpp +631 -0
- data/ext/cadical/cadical/src/backtrack.cpp +177 -0
- data/ext/cadical/cadical/src/backward.cpp +231 -0
- data/ext/cadical/cadical/src/bins.cpp +22 -0
- data/ext/cadical/cadical/src/bins.hpp +22 -0
- data/ext/cadical/cadical/src/block.cpp +824 -0
- data/ext/cadical/cadical/src/block.hpp +37 -0
- data/ext/cadical/cadical/src/cadical.cpp +1026 -0
- data/ext/cadical/cadical/src/cadical.hpp +1419 -0
- data/ext/cadical/cadical/src/ccadical.cpp +208 -0
- data/ext/cadical/cadical/src/ccadical.h +74 -0
- data/ext/cadical/cadical/src/checker.cpp +649 -0
- data/ext/cadical/cadical/src/checker.hpp +173 -0
- data/ext/cadical/cadical/src/clause.cpp +689 -0
- data/ext/cadical/cadical/src/clause.hpp +190 -0
- data/ext/cadical/cadical/src/collect.cpp +545 -0
- data/ext/cadical/cadical/src/compact.cpp +550 -0
- data/ext/cadical/cadical/src/condition.cpp +940 -0
- data/ext/cadical/cadical/src/config.cpp +101 -0
- data/ext/cadical/cadical/src/config.hpp +20 -0
- data/ext/cadical/cadical/src/congruence.cpp +7880 -0
- data/ext/cadical/cadical/src/congruence.hpp +757 -0
- data/ext/cadical/cadical/src/constrain.cpp +64 -0
- data/ext/cadical/cadical/src/contract.cpp +27 -0
- data/ext/cadical/cadical/src/contract.hpp +139 -0
- data/ext/cadical/cadical/src/cover.cpp +704 -0
- data/ext/cadical/cadical/src/cover.hpp +34 -0
- data/ext/cadical/cadical/src/decide.cpp +347 -0
- data/ext/cadical/cadical/src/decompose.cpp +738 -0
- data/ext/cadical/cadical/src/decompose.hpp +23 -0
- data/ext/cadical/cadical/src/deduplicate.cpp +275 -0
- data/ext/cadical/cadical/src/definition.cpp +283 -0
- data/ext/cadical/cadical/src/delay.hpp +38 -0
- data/ext/cadical/cadical/src/drattracer.cpp +153 -0
- data/ext/cadical/cadical/src/drattracer.hpp +55 -0
- data/ext/cadical/cadical/src/elim.cpp +1171 -0
- data/ext/cadical/cadical/src/elim.hpp +53 -0
- data/ext/cadical/cadical/src/elimfast.cpp +570 -0
- data/ext/cadical/cadical/src/ema.cpp +95 -0
- data/ext/cadical/cadical/src/ema.hpp +68 -0
- data/ext/cadical/cadical/src/extend.cpp +289 -0
- data/ext/cadical/cadical/src/external.cpp +1034 -0
- data/ext/cadical/cadical/src/external.hpp +487 -0
- data/ext/cadical/cadical/src/external_propagate.cpp +1316 -0
- data/ext/cadical/cadical/src/factor.cpp +1011 -0
- data/ext/cadical/cadical/src/factor.hpp +54 -0
- data/ext/cadical/cadical/src/file.cpp +506 -0
- data/ext/cadical/cadical/src/file.hpp +210 -0
- data/ext/cadical/cadical/src/flags.cpp +135 -0
- data/ext/cadical/cadical/src/flags.hpp +93 -0
- data/ext/cadical/cadical/src/flip.cpp +269 -0
- data/ext/cadical/cadical/src/format.cpp +89 -0
- data/ext/cadical/cadical/src/format.hpp +36 -0
- data/ext/cadical/cadical/src/frattracer.cpp +277 -0
- data/ext/cadical/cadical/src/frattracer.hpp +67 -0
- data/ext/cadical/cadical/src/gates.cpp +766 -0
- data/ext/cadical/cadical/src/heap.hpp +212 -0
- data/ext/cadical/cadical/src/idruptracer.cpp +566 -0
- data/ext/cadical/cadical/src/idruptracer.hpp +112 -0
- data/ext/cadical/cadical/src/instantiate.cpp +365 -0
- data/ext/cadical/cadical/src/instantiate.hpp +45 -0
- data/ext/cadical/cadical/src/internal.cpp +1265 -0
- data/ext/cadical/cadical/src/internal.hpp +1941 -0
- data/ext/cadical/cadical/src/inttypes.hpp +34 -0
- data/ext/cadical/cadical/src/ipasir.cpp +47 -0
- data/ext/cadical/cadical/src/ipasir.h +37 -0
- data/ext/cadical/cadical/src/kitten.c +2599 -0
- data/ext/cadical/cadical/src/kitten.h +97 -0
- data/ext/cadical/cadical/src/level.hpp +33 -0
- data/ext/cadical/cadical/src/lidruptracer.cpp +657 -0
- data/ext/cadical/cadical/src/lidruptracer.hpp +122 -0
- data/ext/cadical/cadical/src/limit.cpp +146 -0
- data/ext/cadical/cadical/src/limit.hpp +168 -0
- data/ext/cadical/cadical/src/logging.cpp +214 -0
- data/ext/cadical/cadical/src/logging.hpp +98 -0
- data/ext/cadical/cadical/src/lookahead.cpp +520 -0
- data/ext/cadical/cadical/src/lratchecker.cpp +833 -0
- data/ext/cadical/cadical/src/lratchecker.hpp +168 -0
- data/ext/cadical/cadical/src/lrattracer.cpp +200 -0
- data/ext/cadical/cadical/src/lrattracer.hpp +61 -0
- data/ext/cadical/cadical/src/lucky.cpp +506 -0
- data/ext/cadical/cadical/src/message.cpp +218 -0
- data/ext/cadical/cadical/src/message.hpp +65 -0
- data/ext/cadical/cadical/src/minimize.cpp +224 -0
- data/ext/cadical/cadical/src/mobical.cpp +5588 -0
- data/ext/cadical/cadical/src/occs.cpp +52 -0
- data/ext/cadical/cadical/src/occs.hpp +36 -0
- data/ext/cadical/cadical/src/options.cpp +359 -0
- data/ext/cadical/cadical/src/options.hpp +442 -0
- data/ext/cadical/cadical/src/parse.cpp +471 -0
- data/ext/cadical/cadical/src/parse.hpp +75 -0
- data/ext/cadical/cadical/src/phases.cpp +56 -0
- data/ext/cadical/cadical/src/phases.hpp +19 -0
- data/ext/cadical/cadical/src/probe.cpp +990 -0
- data/ext/cadical/cadical/src/profile.cpp +107 -0
- data/ext/cadical/cadical/src/profile.hpp +283 -0
- data/ext/cadical/cadical/src/proof.cpp +691 -0
- data/ext/cadical/cadical/src/proof.hpp +125 -0
- data/ext/cadical/cadical/src/propagate.cpp +584 -0
- data/ext/cadical/cadical/src/queue.cpp +90 -0
- data/ext/cadical/cadical/src/queue.hpp +74 -0
- data/ext/cadical/cadical/src/radix.hpp +180 -0
- data/ext/cadical/cadical/src/random.cpp +207 -0
- data/ext/cadical/cadical/src/random.h +44 -0
- data/ext/cadical/cadical/src/random.hpp +98 -0
- data/ext/cadical/cadical/src/range.hpp +125 -0
- data/ext/cadical/cadical/src/reap.cpp +127 -0
- data/ext/cadical/cadical/src/reap.hpp +28 -0
- data/ext/cadical/cadical/src/reduce.cpp +278 -0
- data/ext/cadical/cadical/src/reluctant.hpp +82 -0
- data/ext/cadical/cadical/src/rephase.cpp +402 -0
- data/ext/cadical/cadical/src/report.cpp +313 -0
- data/ext/cadical/cadical/src/resources.cpp +160 -0
- data/ext/cadical/cadical/src/resources.hpp +16 -0
- data/ext/cadical/cadical/src/restart.cpp +178 -0
- data/ext/cadical/cadical/src/restore.cpp +267 -0
- data/ext/cadical/cadical/src/score.cpp +51 -0
- data/ext/cadical/cadical/src/score.hpp +16 -0
- data/ext/cadical/cadical/src/shrink.cpp +507 -0
- data/ext/cadical/cadical/src/signal.cpp +136 -0
- data/ext/cadical/cadical/src/signal.hpp +33 -0
- data/ext/cadical/cadical/src/solution.cpp +50 -0
- data/ext/cadical/cadical/src/solver.cpp +1871 -0
- data/ext/cadical/cadical/src/stable.cpp +31 -0
- data/ext/cadical/cadical/src/stack.h +110 -0
- data/ext/cadical/cadical/src/stats.cpp +920 -0
- data/ext/cadical/cadical/src/stats.hpp +418 -0
- data/ext/cadical/cadical/src/subsume.cpp +645 -0
- data/ext/cadical/cadical/src/sweep.cpp +1960 -0
- data/ext/cadical/cadical/src/sweep.hpp +61 -0
- data/ext/cadical/cadical/src/terminal.cpp +38 -0
- data/ext/cadical/cadical/src/terminal.hpp +96 -0
- data/ext/cadical/cadical/src/ternary.cpp +450 -0
- data/ext/cadical/cadical/src/testing.hpp +24 -0
- data/ext/cadical/cadical/src/tier.cpp +189 -0
- data/ext/cadical/cadical/src/tracer.hpp +186 -0
- data/ext/cadical/cadical/src/transred.cpp +253 -0
- data/ext/cadical/cadical/src/unstable.cpp +29 -0
- data/ext/cadical/cadical/src/util.cpp +129 -0
- data/ext/cadical/cadical/src/util.hpp +181 -0
- data/ext/cadical/cadical/src/var.cpp +39 -0
- data/ext/cadical/cadical/src/var.hpp +22 -0
- data/ext/cadical/cadical/src/veripbtracer.cpp +427 -0
- data/ext/cadical/cadical/src/veripbtracer.hpp +106 -0
- data/ext/cadical/cadical/src/version.cpp +107 -0
- data/ext/cadical/cadical/src/version.hpp +13 -0
- data/ext/cadical/cadical/src/vivify.cpp +1893 -0
- data/ext/cadical/cadical/src/vivify.hpp +50 -0
- data/ext/cadical/cadical/src/walk.cpp +1088 -0
- data/ext/cadical/cadical/src/walk.hpp +91 -0
- data/ext/cadical/cadical/src/walk_full_occs.cpp +966 -0
- data/ext/cadical/cadical/src/warmup.cpp +403 -0
- data/ext/cadical/cadical/src/watch.cpp +126 -0
- data/ext/cadical/cadical/src/watch.hpp +77 -0
- data/ext/cadical/cadical_ext.c +778 -0
- data/ext/cadical/extconf.rb +26 -0
- data/lib/cadical/version.rb +3 -0
- data/lib/cadical.rb +12 -0
- metadata +218 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#ifndef _file_hpp_INCLUDED
|
|
2
|
+
#define _file_hpp_INCLUDED
|
|
3
|
+
|
|
4
|
+
#include <cassert>
|
|
5
|
+
#include <cstdint>
|
|
6
|
+
#include <cstdio>
|
|
7
|
+
#include <cstdlib>
|
|
8
|
+
#include <vector>
|
|
9
|
+
|
|
10
|
+
#ifndef NDEBUG
|
|
11
|
+
#include <climits>
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
/*------------------------------------------------------------------------*/
|
|
15
|
+
#ifndef NUNLOCKED
|
|
16
|
+
#define cadical_putc_unlocked putc_unlocked
|
|
17
|
+
#define cadical_getc_unlocked getc_unlocked
|
|
18
|
+
#else
|
|
19
|
+
#define cadical_putc_unlocked putc
|
|
20
|
+
#define cadical_getc_unlocked getc
|
|
21
|
+
#endif
|
|
22
|
+
/*------------------------------------------------------------------------*/
|
|
23
|
+
|
|
24
|
+
namespace CaDiCaL {
|
|
25
|
+
|
|
26
|
+
// Wraps a 'C' file 'FILE' with name and supports zipped reading and writing
|
|
27
|
+
// through 'popen' using external helper tools. Reading has line numbers.
|
|
28
|
+
// Compression and decompression relies on external utilities, e.g., 'gzip',
|
|
29
|
+
// 'bzip2', 'xz', and '7z', which should be in the 'PATH'.
|
|
30
|
+
|
|
31
|
+
struct Internal;
|
|
32
|
+
|
|
33
|
+
class File {
|
|
34
|
+
|
|
35
|
+
Internal *internal;
|
|
36
|
+
#if !defined(QUIET) || !defined(NDEBUG)
|
|
37
|
+
bool writing;
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
int close_file; // need to close file (1=fclose, 2=pclose, 3=pipe)
|
|
41
|
+
int child_pid;
|
|
42
|
+
FILE *file;
|
|
43
|
+
char *_name;
|
|
44
|
+
uint64_t _lineno;
|
|
45
|
+
uint64_t _bytes;
|
|
46
|
+
|
|
47
|
+
File (Internal *, bool, int, int, FILE *, const char *);
|
|
48
|
+
|
|
49
|
+
static FILE *open_file (Internal *, const char *path, const char *mode);
|
|
50
|
+
static FILE *read_file (Internal *, const char *path);
|
|
51
|
+
static FILE *write_file (Internal *, const char *path);
|
|
52
|
+
|
|
53
|
+
static void split_str (const char *, std::vector<char *> &);
|
|
54
|
+
static void delete_str_vector (std::vector<char *> &);
|
|
55
|
+
|
|
56
|
+
static FILE *open_pipe (Internal *, const char *fmt, const char *path,
|
|
57
|
+
const char *mode);
|
|
58
|
+
static FILE *read_pipe (Internal *, const char *fmt, const int *sig,
|
|
59
|
+
const char *path);
|
|
60
|
+
#ifndef _WIN32
|
|
61
|
+
static FILE *write_pipe (Internal *, const char *fmt, const char *path,
|
|
62
|
+
int &child_pid);
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
public:
|
|
66
|
+
static char *find_program (const char *prg); // search in 'PATH'
|
|
67
|
+
static bool exists (const char *path); // file exists?
|
|
68
|
+
static bool writable (const char *path); // can write to that file?
|
|
69
|
+
static size_t size (const char *path); // file size in bytes
|
|
70
|
+
|
|
71
|
+
bool piping (); // Is opened file a pipe?
|
|
72
|
+
|
|
73
|
+
// Does the file match the file type signature.
|
|
74
|
+
//
|
|
75
|
+
static bool match (Internal *, const char *path, const int *sig);
|
|
76
|
+
|
|
77
|
+
// Read from existing file. Assume given name.
|
|
78
|
+
//
|
|
79
|
+
static File *read (Internal *, FILE *f, const char *name);
|
|
80
|
+
|
|
81
|
+
// Open file from path name for reading (possibly through opening a pipe
|
|
82
|
+
// to a decompression utility, based on the suffix).
|
|
83
|
+
//
|
|
84
|
+
static File *read (Internal *, const char *path);
|
|
85
|
+
|
|
86
|
+
// Same for writing as for reading above.
|
|
87
|
+
//
|
|
88
|
+
static File *write (Internal *, FILE *, const char *name);
|
|
89
|
+
static File *write (Internal *, const char *path);
|
|
90
|
+
|
|
91
|
+
~File ();
|
|
92
|
+
|
|
93
|
+
// Using the 'unlocked' versions here is way faster but
|
|
94
|
+
// not thread safe if the same file is used by different
|
|
95
|
+
// threads, which on the other hand currently is impossible.
|
|
96
|
+
|
|
97
|
+
int get () {
|
|
98
|
+
assert (!writing);
|
|
99
|
+
int res = cadical_getc_unlocked (file);
|
|
100
|
+
if (res == '\n')
|
|
101
|
+
_lineno++;
|
|
102
|
+
if (res != EOF)
|
|
103
|
+
_bytes++;
|
|
104
|
+
return res;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
bool put (char ch) {
|
|
108
|
+
assert (writing);
|
|
109
|
+
if (cadical_putc_unlocked (ch, file) == EOF)
|
|
110
|
+
return false;
|
|
111
|
+
_bytes++;
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
bool endl () { return put ('\n'); }
|
|
116
|
+
|
|
117
|
+
bool put (unsigned char ch) {
|
|
118
|
+
assert (writing);
|
|
119
|
+
if (cadical_putc_unlocked (ch, file) == EOF)
|
|
120
|
+
return false;
|
|
121
|
+
_bytes++;
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
bool put (const char *s) {
|
|
126
|
+
for (const char *p = s; *p; p++)
|
|
127
|
+
if (!put (*p))
|
|
128
|
+
return false;
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
bool put (int lit) {
|
|
133
|
+
assert (writing);
|
|
134
|
+
if (!lit)
|
|
135
|
+
return put ('0');
|
|
136
|
+
else if (lit == -2147483648) {
|
|
137
|
+
assert (lit == INT_MIN);
|
|
138
|
+
return put ("-2147483648");
|
|
139
|
+
} else {
|
|
140
|
+
char buffer[11];
|
|
141
|
+
int i = sizeof buffer;
|
|
142
|
+
buffer[--i] = 0;
|
|
143
|
+
assert (lit != INT_MIN);
|
|
144
|
+
unsigned idx = abs (lit);
|
|
145
|
+
while (idx) {
|
|
146
|
+
assert (i > 0);
|
|
147
|
+
buffer[--i] = '0' + idx % 10;
|
|
148
|
+
idx /= 10;
|
|
149
|
+
}
|
|
150
|
+
if (lit < 0 && !put ('-'))
|
|
151
|
+
return false;
|
|
152
|
+
return put (buffer + i);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
bool put (int64_t l) {
|
|
157
|
+
assert (writing);
|
|
158
|
+
if (!l)
|
|
159
|
+
return put ('0');
|
|
160
|
+
else if (l == INT64_MIN) {
|
|
161
|
+
assert (sizeof l == 8);
|
|
162
|
+
return put ("-9223372036854775808");
|
|
163
|
+
} else {
|
|
164
|
+
char buffer[21];
|
|
165
|
+
int i = sizeof buffer;
|
|
166
|
+
buffer[--i] = 0;
|
|
167
|
+
assert (l != INT64_MIN);
|
|
168
|
+
uint64_t k = l < 0 ? -l : l;
|
|
169
|
+
while (k) {
|
|
170
|
+
assert (i > 0);
|
|
171
|
+
buffer[--i] = '0' + k % 10;
|
|
172
|
+
k /= 10;
|
|
173
|
+
}
|
|
174
|
+
if (l < 0 && !put ('-'))
|
|
175
|
+
return false;
|
|
176
|
+
return put (buffer + i);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
bool put (uint64_t l) {
|
|
181
|
+
assert (writing);
|
|
182
|
+
if (!l)
|
|
183
|
+
return put ('0');
|
|
184
|
+
else {
|
|
185
|
+
char buffer[22];
|
|
186
|
+
int i = sizeof buffer;
|
|
187
|
+
buffer[--i] = 0;
|
|
188
|
+
while (l) {
|
|
189
|
+
assert (i > 0);
|
|
190
|
+
buffer[--i] = '0' + l % 10;
|
|
191
|
+
l /= 10;
|
|
192
|
+
}
|
|
193
|
+
return put (buffer + i);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const char *name () const { return _name; }
|
|
198
|
+
uint64_t lineno () const { return _lineno; }
|
|
199
|
+
uint64_t bytes () const { return _bytes; }
|
|
200
|
+
|
|
201
|
+
void connect_internal (Internal *i) { internal = i; }
|
|
202
|
+
bool closed () { return !file; }
|
|
203
|
+
|
|
204
|
+
void close (bool print = false);
|
|
205
|
+
void flush ();
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
} // namespace CaDiCaL
|
|
209
|
+
|
|
210
|
+
#endif
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#include "internal.hpp"
|
|
2
|
+
|
|
3
|
+
namespace CaDiCaL {
|
|
4
|
+
|
|
5
|
+
void Internal::mark_fixed (int lit) {
|
|
6
|
+
if (external->fixed_listener) {
|
|
7
|
+
int elit = externalize (lit);
|
|
8
|
+
assert (elit);
|
|
9
|
+
const int eidx = abs (elit);
|
|
10
|
+
if (!external->ervars[eidx])
|
|
11
|
+
external->fixed_listener->notify_fixed_assignment (elit);
|
|
12
|
+
}
|
|
13
|
+
Flags &f = flags (lit);
|
|
14
|
+
assert (f.status == Flags::ACTIVE);
|
|
15
|
+
f.status = Flags::FIXED;
|
|
16
|
+
LOG ("fixed %d", abs (lit));
|
|
17
|
+
stats.all.fixed++;
|
|
18
|
+
stats.now.fixed++;
|
|
19
|
+
stats.inactive++;
|
|
20
|
+
assert (stats.active);
|
|
21
|
+
stats.active--;
|
|
22
|
+
assert (!active (lit));
|
|
23
|
+
assert (f.fixed ());
|
|
24
|
+
|
|
25
|
+
if (external_prop && private_steps) {
|
|
26
|
+
// If pre/inprocessing found a fixed assignment, we want the propagator
|
|
27
|
+
// to know about it.
|
|
28
|
+
// But at that point it is not guaranteed to be already on the trail, so
|
|
29
|
+
// notification will happen only later.
|
|
30
|
+
assert (!level || in_mode (BACKBONE));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
void Internal::mark_eliminated (int lit) {
|
|
35
|
+
Flags &f = flags (lit);
|
|
36
|
+
assert (f.status == Flags::ACTIVE);
|
|
37
|
+
f.status = Flags::ELIMINATED;
|
|
38
|
+
LOG ("eliminated %d", abs (lit));
|
|
39
|
+
stats.all.eliminated++;
|
|
40
|
+
stats.now.eliminated++;
|
|
41
|
+
stats.inactive++;
|
|
42
|
+
assert (stats.active);
|
|
43
|
+
stats.active--;
|
|
44
|
+
assert (!active (lit));
|
|
45
|
+
assert (f.eliminated ());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
void Internal::mark_pure (int lit) {
|
|
49
|
+
Flags &f = flags (lit);
|
|
50
|
+
assert (f.status == Flags::ACTIVE);
|
|
51
|
+
f.status = Flags::PURE;
|
|
52
|
+
LOG ("pure %d", abs (lit));
|
|
53
|
+
stats.all.pure++;
|
|
54
|
+
stats.now.pure++;
|
|
55
|
+
stats.inactive++;
|
|
56
|
+
assert (stats.active);
|
|
57
|
+
stats.active--;
|
|
58
|
+
assert (!active (lit));
|
|
59
|
+
assert (f.pure ());
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
void Internal::mark_substituted (int lit) {
|
|
63
|
+
Flags &f = flags (lit);
|
|
64
|
+
assert (f.status == Flags::ACTIVE);
|
|
65
|
+
f.status = Flags::SUBSTITUTED;
|
|
66
|
+
LOG ("substituted %d", abs (lit));
|
|
67
|
+
stats.all.substituted++;
|
|
68
|
+
stats.now.substituted++;
|
|
69
|
+
stats.inactive++;
|
|
70
|
+
assert (stats.active);
|
|
71
|
+
stats.active--;
|
|
72
|
+
assert (!active (lit));
|
|
73
|
+
assert (f.substituted ());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
void Internal::mark_active (int lit) {
|
|
77
|
+
Flags &f = flags (lit);
|
|
78
|
+
assert (f.status == Flags::UNUSED);
|
|
79
|
+
f.status = Flags::ACTIVE;
|
|
80
|
+
LOG ("activate %d previously unused", abs (lit));
|
|
81
|
+
assert (stats.inactive);
|
|
82
|
+
stats.inactive--;
|
|
83
|
+
assert (stats.unused);
|
|
84
|
+
stats.unused--;
|
|
85
|
+
stats.active++;
|
|
86
|
+
assert (active (lit));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void Internal::reactivate (int lit) {
|
|
90
|
+
assert (!active (lit));
|
|
91
|
+
Flags &f = flags (lit);
|
|
92
|
+
assert (f.status != Flags::FIXED);
|
|
93
|
+
assert (f.status != Flags::UNUSED);
|
|
94
|
+
#ifdef LOGGING
|
|
95
|
+
const char *msg = 0;
|
|
96
|
+
#endif
|
|
97
|
+
switch (f.status) {
|
|
98
|
+
default:
|
|
99
|
+
case Flags::ELIMINATED:
|
|
100
|
+
assert (f.status == Flags::ELIMINATED);
|
|
101
|
+
assert (stats.now.eliminated > 0);
|
|
102
|
+
stats.now.eliminated--;
|
|
103
|
+
#ifdef LOGGING
|
|
104
|
+
msg = "eliminated";
|
|
105
|
+
#endif
|
|
106
|
+
break;
|
|
107
|
+
case Flags::SUBSTITUTED:
|
|
108
|
+
#ifdef LOGGING
|
|
109
|
+
msg = "substituted";
|
|
110
|
+
#endif
|
|
111
|
+
assert (stats.now.substituted > 0);
|
|
112
|
+
stats.now.substituted--;
|
|
113
|
+
break;
|
|
114
|
+
case Flags::PURE:
|
|
115
|
+
#ifdef LOGGING
|
|
116
|
+
msg = "pure literal";
|
|
117
|
+
#endif
|
|
118
|
+
assert (stats.now.pure > 0);
|
|
119
|
+
stats.now.pure--;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
#ifdef LOGGING
|
|
123
|
+
assert (msg);
|
|
124
|
+
LOG ("reactivate previously %s %d", msg, abs (lit));
|
|
125
|
+
#endif
|
|
126
|
+
f.status = Flags::ACTIVE;
|
|
127
|
+
f.sweep = false;
|
|
128
|
+
assert (active (lit));
|
|
129
|
+
stats.reactivated++;
|
|
130
|
+
assert (stats.inactive > 0);
|
|
131
|
+
stats.inactive--;
|
|
132
|
+
stats.active++;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
} // namespace CaDiCaL
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#ifndef _flags_hpp_INCLUDED
|
|
2
|
+
#define _flags_hpp_INCLUDED
|
|
3
|
+
|
|
4
|
+
namespace CaDiCaL {
|
|
5
|
+
|
|
6
|
+
struct Flags { // Variable flags.
|
|
7
|
+
|
|
8
|
+
// The first set of flags is related to 'analyze' and 'minimize'.
|
|
9
|
+
//
|
|
10
|
+
bool seen : 1; // seen in generating first UIP clause in 'analyze'
|
|
11
|
+
bool keep : 1; // keep in learned clause in 'minimize'
|
|
12
|
+
bool poison : 1; // can not be removed in 'minimize'
|
|
13
|
+
bool removable : 1; // can be removed in 'minimize'
|
|
14
|
+
bool shrinkable : 1; // can be removed in 'shrink'
|
|
15
|
+
bool added : 1; // has already been added to lrat_chain (in 'minimize')
|
|
16
|
+
|
|
17
|
+
// These three variable flags are used to schedule clauses in subsumption
|
|
18
|
+
// ('subsume'), variables in bounded variable elimination ('elim') and in
|
|
19
|
+
// hyper ternary resolution ('ternary').
|
|
20
|
+
//
|
|
21
|
+
bool elim : 1; // removed since last 'elim' round (*)
|
|
22
|
+
bool subsume : 1; // added since last 'subsume' round (*)
|
|
23
|
+
bool ternary : 1; // added in ternary clause since last 'ternary' (*)
|
|
24
|
+
bool sweep : 1;
|
|
25
|
+
bool blockable : 1;
|
|
26
|
+
|
|
27
|
+
unsigned char
|
|
28
|
+
marked_signed : 2; // generate correct LRAT chains in decompose
|
|
29
|
+
unsigned char factor : 2;
|
|
30
|
+
|
|
31
|
+
// These literal flags are used by blocked clause elimination ('block').
|
|
32
|
+
//
|
|
33
|
+
unsigned char block : 2; // removed since last 'block' round (*)
|
|
34
|
+
unsigned char skip : 2; // skip this literal as blocking literal
|
|
35
|
+
bool backbone1, backbone0;
|
|
36
|
+
// Bits for handling assumptions.
|
|
37
|
+
//
|
|
38
|
+
unsigned char assumed : 2;
|
|
39
|
+
unsigned char failed : 2; // 0 if not part of failure
|
|
40
|
+
// 1 if positive lit is in failure
|
|
41
|
+
// 2 if negated lit is in failure
|
|
42
|
+
bool factored_but_on_reconstruction_stack : 1;
|
|
43
|
+
|
|
44
|
+
enum {
|
|
45
|
+
UNUSED = 0,
|
|
46
|
+
ACTIVE = 1,
|
|
47
|
+
FIXED = 2,
|
|
48
|
+
ELIMINATED = 3,
|
|
49
|
+
SUBSTITUTED = 4,
|
|
50
|
+
PURE = 5
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
unsigned char status : 3;
|
|
54
|
+
|
|
55
|
+
// Initialized explicitly in 'Internal::init' through this function.
|
|
56
|
+
//
|
|
57
|
+
Flags () {
|
|
58
|
+
seen = keep = poison = removable = shrinkable = added = sweep =
|
|
59
|
+
backbone1 = backbone0 = false;
|
|
60
|
+
subsume = elim = ternary = true;
|
|
61
|
+
block = 3u;
|
|
62
|
+
skip = assumed = failed = marked_signed = factor = 0;
|
|
63
|
+
status = UNUSED;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
bool unused () const { return status == UNUSED; }
|
|
67
|
+
bool active () const { return status == ACTIVE; }
|
|
68
|
+
bool fixed () const { return status == FIXED; }
|
|
69
|
+
bool eliminated () const { return status == ELIMINATED; }
|
|
70
|
+
bool substituted () const { return status == SUBSTITUTED; }
|
|
71
|
+
bool pure () const { return status == PURE; }
|
|
72
|
+
|
|
73
|
+
// The flags marked with '(*)' are copied during 'External::copy_flags',
|
|
74
|
+
// which in essence means they are reset in the copy if they were clear.
|
|
75
|
+
// This avoids the effort of fruitless preprocessing the copy.
|
|
76
|
+
|
|
77
|
+
void copy (Flags &dst) const {
|
|
78
|
+
dst.elim = elim;
|
|
79
|
+
dst.subsume = subsume;
|
|
80
|
+
dst.ternary = ternary;
|
|
81
|
+
dst.block = block;
|
|
82
|
+
dst.sweep = sweep;
|
|
83
|
+
dst.backbone0 = backbone0;
|
|
84
|
+
dst.backbone1 = backbone1;
|
|
85
|
+
dst.added = added;
|
|
86
|
+
dst.factor = factor;
|
|
87
|
+
// seen, keep, poison, removable, shrinkable are unused
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
} // namespace CaDiCaL
|
|
92
|
+
|
|
93
|
+
#endif
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
#include "internal.hpp"
|
|
2
|
+
|
|
3
|
+
namespace CaDiCaL {
|
|
4
|
+
|
|
5
|
+
bool Internal::flip (int lit) {
|
|
6
|
+
|
|
7
|
+
// Do not try to flip inactive literals except for unused variables.
|
|
8
|
+
|
|
9
|
+
if (!active (lit) && !flags (lit).unused ())
|
|
10
|
+
return false;
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
if (flags (lit).unused ()) {
|
|
14
|
+
assert (lit <= max_var);
|
|
15
|
+
mark_active (lit);
|
|
16
|
+
set_val (lit, 1);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// TODO: Unused case is not handled yet.
|
|
22
|
+
// if (flags (lit).unused ()) return false;
|
|
23
|
+
|
|
24
|
+
// Need to reestablish proper watching invariants as if there are no
|
|
25
|
+
// blocking literals as flipping in principle does not work with them.
|
|
26
|
+
|
|
27
|
+
if (propergated < trail.size ())
|
|
28
|
+
propergate ();
|
|
29
|
+
|
|
30
|
+
LOG ("trying to flip %d", lit);
|
|
31
|
+
|
|
32
|
+
const int idx = vidx (lit);
|
|
33
|
+
const signed char original_value = vals[idx];
|
|
34
|
+
assert (original_value);
|
|
35
|
+
lit = original_value < 0 ? -idx : idx;
|
|
36
|
+
assert (val (lit) > 0);
|
|
37
|
+
|
|
38
|
+
// Here we go over all the clauses in which 'lit' is watched by 'lit' and
|
|
39
|
+
// check whether assigning 'lit' to false would break watching invariants
|
|
40
|
+
// or even make the clause false. We also try to find replacement
|
|
41
|
+
// watches in case this fixes the watching invariant. This code is very
|
|
42
|
+
// similar to propagation of a literal in 'Internal::propagate'.
|
|
43
|
+
|
|
44
|
+
bool res = true;
|
|
45
|
+
|
|
46
|
+
Watches &ws = watches (lit);
|
|
47
|
+
const const_watch_iterator eow = ws.end ();
|
|
48
|
+
watch_iterator bow = ws.begin ();
|
|
49
|
+
|
|
50
|
+
// We first go over binary watches/clauses first as this is cheaper and
|
|
51
|
+
// has higher chance of failure and we can not use blocking literals.
|
|
52
|
+
|
|
53
|
+
for (const_watch_iterator i = bow; i != eow; i++) {
|
|
54
|
+
const Watch w = *i;
|
|
55
|
+
if (!w.binary ())
|
|
56
|
+
continue;
|
|
57
|
+
const signed char b = val (w.blit);
|
|
58
|
+
if (b > 0)
|
|
59
|
+
continue;
|
|
60
|
+
assert (b < 0);
|
|
61
|
+
res = false;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (res) {
|
|
66
|
+
const_watch_iterator i = bow;
|
|
67
|
+
watch_iterator j = bow;
|
|
68
|
+
|
|
69
|
+
while (i != eow) {
|
|
70
|
+
|
|
71
|
+
const Watch w = *j++ = *i++;
|
|
72
|
+
|
|
73
|
+
if (w.binary ())
|
|
74
|
+
continue;
|
|
75
|
+
|
|
76
|
+
if (w.clause->garbage) {
|
|
77
|
+
j--;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
literal_iterator lits = w.clause->begin ();
|
|
82
|
+
|
|
83
|
+
const int other = lits[0] ^ lits[1] ^ lit;
|
|
84
|
+
const signed char u = val (other);
|
|
85
|
+
if (u > 0)
|
|
86
|
+
continue;
|
|
87
|
+
|
|
88
|
+
const int size = w.clause->size;
|
|
89
|
+
const literal_iterator middle = lits + w.clause->pos;
|
|
90
|
+
const const_literal_iterator end = lits + size;
|
|
91
|
+
literal_iterator k = middle;
|
|
92
|
+
|
|
93
|
+
int r = 0;
|
|
94
|
+
signed char v = -1;
|
|
95
|
+
while (k != end && (v = val (r = *k)) < 0)
|
|
96
|
+
k++;
|
|
97
|
+
if (v < 0) {
|
|
98
|
+
k = lits + 2;
|
|
99
|
+
assert (w.clause->pos <= size);
|
|
100
|
+
while (k != middle && (v = val (r = *k)) < 0)
|
|
101
|
+
k++;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (v < 0) {
|
|
105
|
+
res = false;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
assert (v > 0);
|
|
110
|
+
assert (lits + 2 <= k), assert (k <= w.clause->end ());
|
|
111
|
+
w.clause->pos = k - lits;
|
|
112
|
+
lits[0] = other, lits[1] = r, *k = lit;
|
|
113
|
+
watch_literal (r, lit, w.clause);
|
|
114
|
+
j--;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (j != i) {
|
|
118
|
+
|
|
119
|
+
while (i != eow)
|
|
120
|
+
*j++ = *i++;
|
|
121
|
+
|
|
122
|
+
ws.resize (j - ws.begin ());
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
#ifdef LOGGING
|
|
126
|
+
if (res)
|
|
127
|
+
LOG ("literal %d can be flipped", lit);
|
|
128
|
+
else
|
|
129
|
+
LOG ("literal %d can not be flipped", lit);
|
|
130
|
+
#endif
|
|
131
|
+
|
|
132
|
+
if (res) {
|
|
133
|
+
|
|
134
|
+
const int idx = vidx (lit);
|
|
135
|
+
const signed char original_value = vals[idx];
|
|
136
|
+
assert (original_value);
|
|
137
|
+
lit = original_value < 0 ? -idx : idx;
|
|
138
|
+
assert (val (lit) > 0);
|
|
139
|
+
|
|
140
|
+
LOG ("flipping value of %d = 1 to %d = -1", lit, lit);
|
|
141
|
+
|
|
142
|
+
set_val (idx, -original_value);
|
|
143
|
+
assert (val (-lit) > 0);
|
|
144
|
+
assert (val (lit) < 0);
|
|
145
|
+
|
|
146
|
+
Var &v = var (idx);
|
|
147
|
+
assert (trail[v.trail] == lit);
|
|
148
|
+
trail[v.trail] = -lit;
|
|
149
|
+
if (opts.ilb) {
|
|
150
|
+
if (!changed_val)
|
|
151
|
+
changed_val = lit;
|
|
152
|
+
else {
|
|
153
|
+
assert (val (changed_val));
|
|
154
|
+
if (v.level < var (changed_val).level) {
|
|
155
|
+
changed_val = lit;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} else
|
|
160
|
+
LOG ("flipping value of %d failed", lit);
|
|
161
|
+
|
|
162
|
+
return res;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
bool Internal::flippable (int lit) {
|
|
166
|
+
|
|
167
|
+
// Can not check inactive literals except for unused variables.
|
|
168
|
+
|
|
169
|
+
if (!active (lit) && !flags (lit).unused ())
|
|
170
|
+
return false;
|
|
171
|
+
|
|
172
|
+
/*
|
|
173
|
+
if (flags (lit).unused ()) {
|
|
174
|
+
assert (lit <= max_var);
|
|
175
|
+
mark_active (lit);
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
*/
|
|
179
|
+
// TODO: Unused case is not handled yet
|
|
180
|
+
// if (flags (lit).unused ()) return false;
|
|
181
|
+
|
|
182
|
+
// Need to reestablish proper watching invariants as if there are no
|
|
183
|
+
// blocking literals as flipping in principle does not work with them.
|
|
184
|
+
|
|
185
|
+
if (propergated < trail.size ())
|
|
186
|
+
propergate ();
|
|
187
|
+
|
|
188
|
+
LOG ("checking whether %d is flippable", lit);
|
|
189
|
+
|
|
190
|
+
const int idx = vidx (lit);
|
|
191
|
+
const signed char original_value = vals[idx];
|
|
192
|
+
assert (original_value);
|
|
193
|
+
lit = original_value < 0 ? -idx : idx;
|
|
194
|
+
assert (val (lit) > 0);
|
|
195
|
+
|
|
196
|
+
// Here we go over all the clauses in which 'lit' is watched by 'lit' and
|
|
197
|
+
// check whether assigning 'lit' to false would break watching invariants
|
|
198
|
+
// or even make the clause false. In contrast to 'flip' we do not try to
|
|
199
|
+
// find replacement literals but do use blocking literals'. Therefore we
|
|
200
|
+
// also do not split the traversal code into two parts.
|
|
201
|
+
|
|
202
|
+
bool res = true;
|
|
203
|
+
|
|
204
|
+
Watches &ws = watches (lit);
|
|
205
|
+
const const_watch_iterator eow = ws.end ();
|
|
206
|
+
for (watch_iterator i = ws.begin (); i != eow; i++) {
|
|
207
|
+
|
|
208
|
+
const Watch w = *i;
|
|
209
|
+
const signed char b = val (w.blit);
|
|
210
|
+
if (b > 0)
|
|
211
|
+
continue;
|
|
212
|
+
assert (b < 0);
|
|
213
|
+
|
|
214
|
+
if (w.binary ()) {
|
|
215
|
+
res = false;
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (w.clause->garbage)
|
|
220
|
+
continue;
|
|
221
|
+
|
|
222
|
+
literal_iterator lits = w.clause->begin ();
|
|
223
|
+
|
|
224
|
+
const int other = lits[0] ^ lits[1] ^ lit;
|
|
225
|
+
const signed char u = val (other);
|
|
226
|
+
if (u > 0) {
|
|
227
|
+
i->blit = other;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const int size = w.clause->size;
|
|
232
|
+
const literal_iterator middle = lits + w.clause->pos;
|
|
233
|
+
const const_literal_iterator end = lits + size;
|
|
234
|
+
literal_iterator k = middle;
|
|
235
|
+
|
|
236
|
+
int r = 0;
|
|
237
|
+
signed char v = -1;
|
|
238
|
+
while (k != end && (v = val (r = *k)) < 0)
|
|
239
|
+
k++;
|
|
240
|
+
if (v < 0) {
|
|
241
|
+
k = lits + 2;
|
|
242
|
+
assert (w.clause->pos <= size);
|
|
243
|
+
while (k != middle && (v = val (r = *k)) < 0)
|
|
244
|
+
k++;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (v < 0) {
|
|
248
|
+
res = false;
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
assert (v > 0);
|
|
253
|
+
assert (lits + 2 <= k);
|
|
254
|
+
assert (k <= w.clause->end ());
|
|
255
|
+
w.clause->pos = k - lits;
|
|
256
|
+
i->blit = r;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
#ifdef LOGGING
|
|
260
|
+
if (res)
|
|
261
|
+
LOG ("literal %d can be flipped", lit);
|
|
262
|
+
else
|
|
263
|
+
LOG ("literal %d can not be flipped", lit);
|
|
264
|
+
#endif
|
|
265
|
+
|
|
266
|
+
return res;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
} // namespace CaDiCaL
|