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.
Files changed (171) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +26 -0
  3. data/README.md +101 -0
  4. data/ext/cadical/cadical/LICENSE +28 -0
  5. data/ext/cadical/cadical/README.md +65 -0
  6. data/ext/cadical/cadical/VERSION +1 -0
  7. data/ext/cadical/cadical/src/analyze.cpp +1360 -0
  8. data/ext/cadical/cadical/src/arena.cpp +30 -0
  9. data/ext/cadical/cadical/src/arena.hpp +105 -0
  10. data/ext/cadical/cadical/src/assume.cpp +616 -0
  11. data/ext/cadical/cadical/src/averages.cpp +34 -0
  12. data/ext/cadical/cadical/src/averages.hpp +37 -0
  13. data/ext/cadical/cadical/src/backbone.cpp +631 -0
  14. data/ext/cadical/cadical/src/backtrack.cpp +177 -0
  15. data/ext/cadical/cadical/src/backward.cpp +231 -0
  16. data/ext/cadical/cadical/src/bins.cpp +22 -0
  17. data/ext/cadical/cadical/src/bins.hpp +22 -0
  18. data/ext/cadical/cadical/src/block.cpp +824 -0
  19. data/ext/cadical/cadical/src/block.hpp +37 -0
  20. data/ext/cadical/cadical/src/cadical.cpp +1026 -0
  21. data/ext/cadical/cadical/src/cadical.hpp +1419 -0
  22. data/ext/cadical/cadical/src/ccadical.cpp +208 -0
  23. data/ext/cadical/cadical/src/ccadical.h +74 -0
  24. data/ext/cadical/cadical/src/checker.cpp +649 -0
  25. data/ext/cadical/cadical/src/checker.hpp +173 -0
  26. data/ext/cadical/cadical/src/clause.cpp +689 -0
  27. data/ext/cadical/cadical/src/clause.hpp +190 -0
  28. data/ext/cadical/cadical/src/collect.cpp +545 -0
  29. data/ext/cadical/cadical/src/compact.cpp +550 -0
  30. data/ext/cadical/cadical/src/condition.cpp +940 -0
  31. data/ext/cadical/cadical/src/config.cpp +101 -0
  32. data/ext/cadical/cadical/src/config.hpp +20 -0
  33. data/ext/cadical/cadical/src/congruence.cpp +7880 -0
  34. data/ext/cadical/cadical/src/congruence.hpp +757 -0
  35. data/ext/cadical/cadical/src/constrain.cpp +64 -0
  36. data/ext/cadical/cadical/src/contract.cpp +27 -0
  37. data/ext/cadical/cadical/src/contract.hpp +139 -0
  38. data/ext/cadical/cadical/src/cover.cpp +704 -0
  39. data/ext/cadical/cadical/src/cover.hpp +34 -0
  40. data/ext/cadical/cadical/src/decide.cpp +347 -0
  41. data/ext/cadical/cadical/src/decompose.cpp +738 -0
  42. data/ext/cadical/cadical/src/decompose.hpp +23 -0
  43. data/ext/cadical/cadical/src/deduplicate.cpp +275 -0
  44. data/ext/cadical/cadical/src/definition.cpp +283 -0
  45. data/ext/cadical/cadical/src/delay.hpp +38 -0
  46. data/ext/cadical/cadical/src/drattracer.cpp +153 -0
  47. data/ext/cadical/cadical/src/drattracer.hpp +55 -0
  48. data/ext/cadical/cadical/src/elim.cpp +1171 -0
  49. data/ext/cadical/cadical/src/elim.hpp +53 -0
  50. data/ext/cadical/cadical/src/elimfast.cpp +570 -0
  51. data/ext/cadical/cadical/src/ema.cpp +95 -0
  52. data/ext/cadical/cadical/src/ema.hpp +68 -0
  53. data/ext/cadical/cadical/src/extend.cpp +289 -0
  54. data/ext/cadical/cadical/src/external.cpp +1034 -0
  55. data/ext/cadical/cadical/src/external.hpp +487 -0
  56. data/ext/cadical/cadical/src/external_propagate.cpp +1316 -0
  57. data/ext/cadical/cadical/src/factor.cpp +1011 -0
  58. data/ext/cadical/cadical/src/factor.hpp +54 -0
  59. data/ext/cadical/cadical/src/file.cpp +506 -0
  60. data/ext/cadical/cadical/src/file.hpp +210 -0
  61. data/ext/cadical/cadical/src/flags.cpp +135 -0
  62. data/ext/cadical/cadical/src/flags.hpp +93 -0
  63. data/ext/cadical/cadical/src/flip.cpp +269 -0
  64. data/ext/cadical/cadical/src/format.cpp +89 -0
  65. data/ext/cadical/cadical/src/format.hpp +36 -0
  66. data/ext/cadical/cadical/src/frattracer.cpp +277 -0
  67. data/ext/cadical/cadical/src/frattracer.hpp +67 -0
  68. data/ext/cadical/cadical/src/gates.cpp +766 -0
  69. data/ext/cadical/cadical/src/heap.hpp +212 -0
  70. data/ext/cadical/cadical/src/idruptracer.cpp +566 -0
  71. data/ext/cadical/cadical/src/idruptracer.hpp +112 -0
  72. data/ext/cadical/cadical/src/instantiate.cpp +365 -0
  73. data/ext/cadical/cadical/src/instantiate.hpp +45 -0
  74. data/ext/cadical/cadical/src/internal.cpp +1265 -0
  75. data/ext/cadical/cadical/src/internal.hpp +1941 -0
  76. data/ext/cadical/cadical/src/inttypes.hpp +34 -0
  77. data/ext/cadical/cadical/src/ipasir.cpp +47 -0
  78. data/ext/cadical/cadical/src/ipasir.h +37 -0
  79. data/ext/cadical/cadical/src/kitten.c +2599 -0
  80. data/ext/cadical/cadical/src/kitten.h +97 -0
  81. data/ext/cadical/cadical/src/level.hpp +33 -0
  82. data/ext/cadical/cadical/src/lidruptracer.cpp +657 -0
  83. data/ext/cadical/cadical/src/lidruptracer.hpp +122 -0
  84. data/ext/cadical/cadical/src/limit.cpp +146 -0
  85. data/ext/cadical/cadical/src/limit.hpp +168 -0
  86. data/ext/cadical/cadical/src/logging.cpp +214 -0
  87. data/ext/cadical/cadical/src/logging.hpp +98 -0
  88. data/ext/cadical/cadical/src/lookahead.cpp +520 -0
  89. data/ext/cadical/cadical/src/lratchecker.cpp +833 -0
  90. data/ext/cadical/cadical/src/lratchecker.hpp +168 -0
  91. data/ext/cadical/cadical/src/lrattracer.cpp +200 -0
  92. data/ext/cadical/cadical/src/lrattracer.hpp +61 -0
  93. data/ext/cadical/cadical/src/lucky.cpp +506 -0
  94. data/ext/cadical/cadical/src/message.cpp +218 -0
  95. data/ext/cadical/cadical/src/message.hpp +65 -0
  96. data/ext/cadical/cadical/src/minimize.cpp +224 -0
  97. data/ext/cadical/cadical/src/mobical.cpp +5588 -0
  98. data/ext/cadical/cadical/src/occs.cpp +52 -0
  99. data/ext/cadical/cadical/src/occs.hpp +36 -0
  100. data/ext/cadical/cadical/src/options.cpp +359 -0
  101. data/ext/cadical/cadical/src/options.hpp +442 -0
  102. data/ext/cadical/cadical/src/parse.cpp +471 -0
  103. data/ext/cadical/cadical/src/parse.hpp +75 -0
  104. data/ext/cadical/cadical/src/phases.cpp +56 -0
  105. data/ext/cadical/cadical/src/phases.hpp +19 -0
  106. data/ext/cadical/cadical/src/probe.cpp +990 -0
  107. data/ext/cadical/cadical/src/profile.cpp +107 -0
  108. data/ext/cadical/cadical/src/profile.hpp +283 -0
  109. data/ext/cadical/cadical/src/proof.cpp +691 -0
  110. data/ext/cadical/cadical/src/proof.hpp +125 -0
  111. data/ext/cadical/cadical/src/propagate.cpp +584 -0
  112. data/ext/cadical/cadical/src/queue.cpp +90 -0
  113. data/ext/cadical/cadical/src/queue.hpp +74 -0
  114. data/ext/cadical/cadical/src/radix.hpp +180 -0
  115. data/ext/cadical/cadical/src/random.cpp +207 -0
  116. data/ext/cadical/cadical/src/random.h +44 -0
  117. data/ext/cadical/cadical/src/random.hpp +98 -0
  118. data/ext/cadical/cadical/src/range.hpp +125 -0
  119. data/ext/cadical/cadical/src/reap.cpp +127 -0
  120. data/ext/cadical/cadical/src/reap.hpp +28 -0
  121. data/ext/cadical/cadical/src/reduce.cpp +278 -0
  122. data/ext/cadical/cadical/src/reluctant.hpp +82 -0
  123. data/ext/cadical/cadical/src/rephase.cpp +402 -0
  124. data/ext/cadical/cadical/src/report.cpp +313 -0
  125. data/ext/cadical/cadical/src/resources.cpp +160 -0
  126. data/ext/cadical/cadical/src/resources.hpp +16 -0
  127. data/ext/cadical/cadical/src/restart.cpp +178 -0
  128. data/ext/cadical/cadical/src/restore.cpp +267 -0
  129. data/ext/cadical/cadical/src/score.cpp +51 -0
  130. data/ext/cadical/cadical/src/score.hpp +16 -0
  131. data/ext/cadical/cadical/src/shrink.cpp +507 -0
  132. data/ext/cadical/cadical/src/signal.cpp +136 -0
  133. data/ext/cadical/cadical/src/signal.hpp +33 -0
  134. data/ext/cadical/cadical/src/solution.cpp +50 -0
  135. data/ext/cadical/cadical/src/solver.cpp +1871 -0
  136. data/ext/cadical/cadical/src/stable.cpp +31 -0
  137. data/ext/cadical/cadical/src/stack.h +110 -0
  138. data/ext/cadical/cadical/src/stats.cpp +920 -0
  139. data/ext/cadical/cadical/src/stats.hpp +418 -0
  140. data/ext/cadical/cadical/src/subsume.cpp +645 -0
  141. data/ext/cadical/cadical/src/sweep.cpp +1960 -0
  142. data/ext/cadical/cadical/src/sweep.hpp +61 -0
  143. data/ext/cadical/cadical/src/terminal.cpp +38 -0
  144. data/ext/cadical/cadical/src/terminal.hpp +96 -0
  145. data/ext/cadical/cadical/src/ternary.cpp +450 -0
  146. data/ext/cadical/cadical/src/testing.hpp +24 -0
  147. data/ext/cadical/cadical/src/tier.cpp +189 -0
  148. data/ext/cadical/cadical/src/tracer.hpp +186 -0
  149. data/ext/cadical/cadical/src/transred.cpp +253 -0
  150. data/ext/cadical/cadical/src/unstable.cpp +29 -0
  151. data/ext/cadical/cadical/src/util.cpp +129 -0
  152. data/ext/cadical/cadical/src/util.hpp +181 -0
  153. data/ext/cadical/cadical/src/var.cpp +39 -0
  154. data/ext/cadical/cadical/src/var.hpp +22 -0
  155. data/ext/cadical/cadical/src/veripbtracer.cpp +427 -0
  156. data/ext/cadical/cadical/src/veripbtracer.hpp +106 -0
  157. data/ext/cadical/cadical/src/version.cpp +107 -0
  158. data/ext/cadical/cadical/src/version.hpp +13 -0
  159. data/ext/cadical/cadical/src/vivify.cpp +1893 -0
  160. data/ext/cadical/cadical/src/vivify.hpp +50 -0
  161. data/ext/cadical/cadical/src/walk.cpp +1088 -0
  162. data/ext/cadical/cadical/src/walk.hpp +91 -0
  163. data/ext/cadical/cadical/src/walk_full_occs.cpp +966 -0
  164. data/ext/cadical/cadical/src/warmup.cpp +403 -0
  165. data/ext/cadical/cadical/src/watch.cpp +126 -0
  166. data/ext/cadical/cadical/src/watch.hpp +77 -0
  167. data/ext/cadical/cadical_ext.c +778 -0
  168. data/ext/cadical/extconf.rb +26 -0
  169. data/lib/cadical/version.rb +3 -0
  170. data/lib/cadical.rb +12 -0
  171. 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