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,61 @@
|
|
|
1
|
+
#ifndef _sweep_hpp_INCLUDED
|
|
2
|
+
#define _sweep_hpp_INCLUDED
|
|
3
|
+
|
|
4
|
+
namespace CaDiCaL {
|
|
5
|
+
|
|
6
|
+
struct Internal;
|
|
7
|
+
|
|
8
|
+
struct sweep_proof_clause {
|
|
9
|
+
unsigned sweep_id; // index for sweeper.clauses
|
|
10
|
+
int64_t cad_id; // cadical id
|
|
11
|
+
unsigned kit_id; // kitten id
|
|
12
|
+
bool learned;
|
|
13
|
+
vector<int> literals;
|
|
14
|
+
vector<unsigned> chain; // lrat
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
struct sweep_blocked_clause {
|
|
18
|
+
int blit;
|
|
19
|
+
int64_t id;
|
|
20
|
+
vector<int> literals;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
struct sweep_binary {
|
|
24
|
+
int lit;
|
|
25
|
+
int other;
|
|
26
|
+
int64_t id;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
struct Sweeper {
|
|
30
|
+
Sweeper (Internal *internal);
|
|
31
|
+
~Sweeper ();
|
|
32
|
+
Internal *internal;
|
|
33
|
+
Random random;
|
|
34
|
+
vector<unsigned> depths;
|
|
35
|
+
int *reprs;
|
|
36
|
+
vector<int> next, prev;
|
|
37
|
+
int first, last, blit;
|
|
38
|
+
unsigned encoded;
|
|
39
|
+
unsigned save;
|
|
40
|
+
vector<int> vars;
|
|
41
|
+
vector<Clause *> clauses;
|
|
42
|
+
vector<sweep_blocked_clause> blocked_clauses;
|
|
43
|
+
bool flush_blocked_clauses;
|
|
44
|
+
vector<int> blockable;
|
|
45
|
+
vector<int> clause;
|
|
46
|
+
vector<int> propagate;
|
|
47
|
+
vector<int> backbone;
|
|
48
|
+
vector<int> partition;
|
|
49
|
+
vector<bool> prev_units;
|
|
50
|
+
vector<sweep_binary> binaries;
|
|
51
|
+
vector<sweep_proof_clause> core[2];
|
|
52
|
+
uint64_t current_ticks;
|
|
53
|
+
struct {
|
|
54
|
+
uint64_t ticks;
|
|
55
|
+
unsigned clauses, depth, vars;
|
|
56
|
+
} limit;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
} // namespace CaDiCaL
|
|
60
|
+
|
|
61
|
+
#endif
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#include "internal.hpp"
|
|
2
|
+
|
|
3
|
+
namespace CaDiCaL {
|
|
4
|
+
|
|
5
|
+
Terminal::Terminal (FILE *f) : file (f), reset_on_exit (false) {
|
|
6
|
+
assert (file);
|
|
7
|
+
int fd = fileno (f);
|
|
8
|
+
assert (fd == 1 || fd == 2);
|
|
9
|
+
use_colors = connected = isatty (fd);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
void Terminal::force_colors () { use_colors = connected = true; }
|
|
13
|
+
void Terminal::force_no_colors () { use_colors = false; }
|
|
14
|
+
void Terminal::force_reset_on_exit () { reset_on_exit = true; }
|
|
15
|
+
|
|
16
|
+
void Terminal::reset () {
|
|
17
|
+
if (!connected)
|
|
18
|
+
return;
|
|
19
|
+
erase_until_end_of_line ();
|
|
20
|
+
cursor (true);
|
|
21
|
+
normal ();
|
|
22
|
+
fflush (file);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
void Terminal::disable () {
|
|
26
|
+
reset ();
|
|
27
|
+
connected = use_colors = false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Terminal::~Terminal () {
|
|
31
|
+
if (reset_on_exit)
|
|
32
|
+
reset ();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
Terminal tout (stdout);
|
|
36
|
+
Terminal terr (stderr);
|
|
37
|
+
|
|
38
|
+
} // namespace CaDiCaL
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#ifndef _terminal_hpp_INCLUDED
|
|
2
|
+
#define _terminal_hpp_INCLUDED
|
|
3
|
+
|
|
4
|
+
namespace CaDiCaL {
|
|
5
|
+
|
|
6
|
+
class Terminal {
|
|
7
|
+
|
|
8
|
+
FILE *file; // 'stdout' or 'stderr'
|
|
9
|
+
bool connected; // Connected to terminal.
|
|
10
|
+
bool use_colors; // Use colors.
|
|
11
|
+
bool reset_on_exit; // Reset on exit.
|
|
12
|
+
|
|
13
|
+
void escape () {
|
|
14
|
+
assert (connected);
|
|
15
|
+
fputs ("\033[", file);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
void color (int color, bool bright) {
|
|
19
|
+
if (!use_colors)
|
|
20
|
+
return;
|
|
21
|
+
assert (connected);
|
|
22
|
+
escape ();
|
|
23
|
+
fputc (bright ? '1' : '0', file);
|
|
24
|
+
fprintf (file, ";%dm", color);
|
|
25
|
+
fflush (file);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
void code (const char *str) {
|
|
29
|
+
if (!connected)
|
|
30
|
+
return;
|
|
31
|
+
escape ();
|
|
32
|
+
fputs (str, file);
|
|
33
|
+
fflush (file);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public:
|
|
37
|
+
Terminal (FILE *file);
|
|
38
|
+
~Terminal ();
|
|
39
|
+
|
|
40
|
+
void disable (); // Assume disconnected in any case.
|
|
41
|
+
void force_colors ();
|
|
42
|
+
void force_no_colors ();
|
|
43
|
+
void force_reset_on_exit ();
|
|
44
|
+
|
|
45
|
+
bool colors () { return use_colors; }
|
|
46
|
+
|
|
47
|
+
operator bool () const { return connected; }
|
|
48
|
+
|
|
49
|
+
void red (bool bright = false) { color (31, bright); }
|
|
50
|
+
void green (bool bright = false) { color (32, bright); }
|
|
51
|
+
void yellow (bool bright = false) { color (33, bright); }
|
|
52
|
+
void blue (bool bright = false) { color (34, bright); }
|
|
53
|
+
void magenta (bool bright = false) { color (35, bright); }
|
|
54
|
+
void black (bool bright = false) { color (90, bright); }
|
|
55
|
+
void cyan (bool bright = false) { color (96, bright); }
|
|
56
|
+
|
|
57
|
+
void bold () { code ("1m"); }
|
|
58
|
+
void normal () { code ("0m"); }
|
|
59
|
+
void inverse () { code ("7m"); }
|
|
60
|
+
void underline () { code ("4m"); }
|
|
61
|
+
|
|
62
|
+
#define MODIFY(CODE) (use_colors ? "\033[" CODE "m" : "")
|
|
63
|
+
|
|
64
|
+
const char *bright_magenta_code () { return MODIFY ("1;35"); }
|
|
65
|
+
const char *magenta_code () { return MODIFY ("0;35"); }
|
|
66
|
+
const char *blue_code () { return MODIFY ("0;34"); }
|
|
67
|
+
const char *bright_blue_code () { return MODIFY ("1;34"); }
|
|
68
|
+
const char *yellow_code () { return MODIFY ("0;33"); }
|
|
69
|
+
const char *bright_yellow_code () { return MODIFY ("1;33"); }
|
|
70
|
+
const char *green_code () { return MODIFY ("0;32"); }
|
|
71
|
+
const char *red_code () { return MODIFY ("0;31"); }
|
|
72
|
+
const char *cyan_code () { return MODIFY ("0;96"); }
|
|
73
|
+
const char *bright_red_code () { return MODIFY ("1;31"); }
|
|
74
|
+
const char *normal_code () { return MODIFY ("0"); }
|
|
75
|
+
const char *bold_code () { return MODIFY ("1"); }
|
|
76
|
+
|
|
77
|
+
void cursor (bool on) { code (on ? "?25h" : "?25l"); }
|
|
78
|
+
|
|
79
|
+
void erase_until_end_of_line () { code ("K"); }
|
|
80
|
+
|
|
81
|
+
void erase_line_if_connected_otherwise_new_line () {
|
|
82
|
+
if (connected)
|
|
83
|
+
code ("1G");
|
|
84
|
+
else
|
|
85
|
+
fputc ('\n', file), fflush (file);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
void reset ();
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
extern Terminal tout; // Terminal of 'stdout' (file descriptor '1')
|
|
92
|
+
extern Terminal terr; // Terminal of 'stderr' (file descriptor '2')
|
|
93
|
+
|
|
94
|
+
} // namespace CaDiCaL
|
|
95
|
+
|
|
96
|
+
#endif
|
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
#include "internal.hpp"
|
|
2
|
+
|
|
3
|
+
namespace CaDiCaL {
|
|
4
|
+
|
|
5
|
+
/*------------------------------------------------------------------------*/
|
|
6
|
+
|
|
7
|
+
// This procedure can be used to produce all possible hyper ternary
|
|
8
|
+
// resolvents from ternary clauses. In contrast to hyper binary resolution
|
|
9
|
+
// we would only try to produce ternary clauses from ternary clauses, i.e.,
|
|
10
|
+
// do not consider quaternary clauses as antecedents. Of course if a binary
|
|
11
|
+
// clause is generated we keep it too. In any case we have to make sure
|
|
12
|
+
// though that we do not add clauses which are already in the formula or are
|
|
13
|
+
// subsumed by a binary clause in the formula. This procedure simulates
|
|
14
|
+
// structural hashing for multiplexer (if-then-else) and binary XOR gates in
|
|
15
|
+
// combination with equivalent literal substitution ('decompose') if run
|
|
16
|
+
// until to completion (which in the current implementation is too costly
|
|
17
|
+
// though and would need to be interleaved more eagerly with equivalent
|
|
18
|
+
// literal substitution). For more information see our CPAIOR'13 paper.
|
|
19
|
+
|
|
20
|
+
/*------------------------------------------------------------------------*/
|
|
21
|
+
|
|
22
|
+
// Check whether a binary clause consisting of the permutation of the given
|
|
23
|
+
// literals already exists.
|
|
24
|
+
|
|
25
|
+
bool Internal::ternary_find_binary_clause (int a, int b) {
|
|
26
|
+
assert (occurring ());
|
|
27
|
+
assert (active (a));
|
|
28
|
+
assert (active (b));
|
|
29
|
+
size_t s = occs (a).size ();
|
|
30
|
+
size_t t = occs (b).size ();
|
|
31
|
+
int lit = s < t ? a : b;
|
|
32
|
+
if (opts.ternaryocclim < (int) occs (lit).size ())
|
|
33
|
+
return true;
|
|
34
|
+
for (const auto &c : occs (lit)) {
|
|
35
|
+
if (c->size != 2)
|
|
36
|
+
continue;
|
|
37
|
+
const int *lits = c->literals;
|
|
38
|
+
if (lits[0] == a && lits[1] == b)
|
|
39
|
+
return true;
|
|
40
|
+
if (lits[0] == b && lits[1] == a)
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/*------------------------------------------------------------------------*/
|
|
47
|
+
|
|
48
|
+
// Check whether a ternary clause consisting of the permutation of the given
|
|
49
|
+
// literals already exists or is subsumed by an existing binary clause.
|
|
50
|
+
|
|
51
|
+
bool Internal::ternary_find_ternary_clause (int a, int b, int c) {
|
|
52
|
+
assert (occurring ());
|
|
53
|
+
assert (active (a));
|
|
54
|
+
assert (active (b));
|
|
55
|
+
assert (active (c));
|
|
56
|
+
size_t r = occs (a).size ();
|
|
57
|
+
size_t s = occs (b).size ();
|
|
58
|
+
size_t t = occs (c).size ();
|
|
59
|
+
int lit;
|
|
60
|
+
if (r < s)
|
|
61
|
+
lit = (t < r) ? c : a;
|
|
62
|
+
else
|
|
63
|
+
lit = (t < s) ? c : b;
|
|
64
|
+
if (opts.ternaryocclim < (int) occs (lit).size ())
|
|
65
|
+
return true;
|
|
66
|
+
for (const auto &d : occs (lit)) {
|
|
67
|
+
const int *lits = d->literals;
|
|
68
|
+
if (d->size == 2) {
|
|
69
|
+
if (lits[0] == a && lits[1] == b)
|
|
70
|
+
return true;
|
|
71
|
+
if (lits[0] == b && lits[1] == a)
|
|
72
|
+
return true;
|
|
73
|
+
if (lits[0] == a && lits[1] == c)
|
|
74
|
+
return true;
|
|
75
|
+
if (lits[0] == c && lits[1] == a)
|
|
76
|
+
return true;
|
|
77
|
+
if (lits[0] == b && lits[1] == c)
|
|
78
|
+
return true;
|
|
79
|
+
if (lits[0] == c && lits[1] == b)
|
|
80
|
+
return true;
|
|
81
|
+
} else {
|
|
82
|
+
assert (d->size == 3);
|
|
83
|
+
if (lits[0] == a && lits[1] == b && lits[2] == c)
|
|
84
|
+
return true;
|
|
85
|
+
if (lits[0] == a && lits[1] == c && lits[2] == b)
|
|
86
|
+
return true;
|
|
87
|
+
if (lits[0] == b && lits[1] == a && lits[2] == c)
|
|
88
|
+
return true;
|
|
89
|
+
if (lits[0] == b && lits[1] == c && lits[2] == a)
|
|
90
|
+
return true;
|
|
91
|
+
if (lits[0] == c && lits[1] == a && lits[2] == b)
|
|
92
|
+
return true;
|
|
93
|
+
if (lits[0] == c && lits[1] == b && lits[2] == a)
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/*------------------------------------------------------------------------*/
|
|
101
|
+
|
|
102
|
+
// Try to resolve the two ternary clauses on the given pivot (assumed to
|
|
103
|
+
// occur positively in the first clause, negatively in the second). If the
|
|
104
|
+
// resolvent has four literals, is tautological, already exists or in the
|
|
105
|
+
// case of a ternary resolvent is subsumed by an existing binary clause then
|
|
106
|
+
// 'false' is returned. The global 'clause' contains the resolvent and
|
|
107
|
+
// needs to be cleared in any case.
|
|
108
|
+
|
|
109
|
+
bool Internal::hyper_ternary_resolve (Clause *c, int pivot, Clause *d) {
|
|
110
|
+
LOG ("hyper binary resolving on pivot %d", pivot);
|
|
111
|
+
LOG (c, "1st antecedent");
|
|
112
|
+
LOG (d, "2nd antecedent");
|
|
113
|
+
stats.ternres++;
|
|
114
|
+
assert (c->size == 3);
|
|
115
|
+
assert (d->size == 3);
|
|
116
|
+
assert (clause.empty ());
|
|
117
|
+
for (const auto &lit : *c)
|
|
118
|
+
if (lit != pivot)
|
|
119
|
+
clause.push_back (lit);
|
|
120
|
+
for (const auto &lit : *d) {
|
|
121
|
+
if (lit == -pivot)
|
|
122
|
+
continue;
|
|
123
|
+
if (lit == clause[0])
|
|
124
|
+
continue;
|
|
125
|
+
if (lit == -clause[0])
|
|
126
|
+
return false;
|
|
127
|
+
if (lit == clause[1])
|
|
128
|
+
continue;
|
|
129
|
+
if (lit == -clause[1])
|
|
130
|
+
return false;
|
|
131
|
+
clause.push_back (lit);
|
|
132
|
+
}
|
|
133
|
+
size_t size = clause.size ();
|
|
134
|
+
if (size > 3)
|
|
135
|
+
return false;
|
|
136
|
+
if (size == 2 && ternary_find_binary_clause (clause[0], clause[1]))
|
|
137
|
+
return false;
|
|
138
|
+
if (size == 3 &&
|
|
139
|
+
ternary_find_ternary_clause (clause[0], clause[1], clause[2]))
|
|
140
|
+
return false;
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/*------------------------------------------------------------------------*/
|
|
145
|
+
|
|
146
|
+
// Produce all ternary resolvents on literal 'pivot' and increment the
|
|
147
|
+
// 'steps' counter by the number of clauses containing 'pivot' which are
|
|
148
|
+
// used during this process. The reason for choosing this metric to measure
|
|
149
|
+
// the effort spent in 'ternary' is that it should be similar to one
|
|
150
|
+
// propagation step during search.
|
|
151
|
+
|
|
152
|
+
void Internal::ternary_lit (int pivot, int64_t &steps, int64_t &htrs) {
|
|
153
|
+
LOG ("starting hyper ternary resolutions on pivot %d", pivot);
|
|
154
|
+
steps -= 1 + cache_lines (occs (pivot).size (), sizeof (Clause *));
|
|
155
|
+
for (const auto &c : occs (pivot)) {
|
|
156
|
+
if (steps < 0)
|
|
157
|
+
break;
|
|
158
|
+
if (htrs < 0)
|
|
159
|
+
break;
|
|
160
|
+
if (c->garbage)
|
|
161
|
+
continue;
|
|
162
|
+
if (c->size != 3) {
|
|
163
|
+
assert (c->size == 2);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (--steps < 0)
|
|
167
|
+
break;
|
|
168
|
+
bool assigned = false;
|
|
169
|
+
for (const auto &lit : *c)
|
|
170
|
+
if (val (lit)) {
|
|
171
|
+
assigned = true;
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
if (assigned)
|
|
175
|
+
continue;
|
|
176
|
+
steps -= 1 + cache_lines (occs (-pivot).size (), sizeof (Clause *));
|
|
177
|
+
for (const auto &d : occs (-pivot)) {
|
|
178
|
+
if (htrs < 0)
|
|
179
|
+
break;
|
|
180
|
+
if (--steps < 0)
|
|
181
|
+
break;
|
|
182
|
+
if (d->garbage)
|
|
183
|
+
continue;
|
|
184
|
+
if (d->size != 3) {
|
|
185
|
+
assert (d->size == 2);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
for (const auto &lit : *d)
|
|
189
|
+
if (val (lit)) {
|
|
190
|
+
assigned = true;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
if (assigned)
|
|
194
|
+
continue;
|
|
195
|
+
assert (clause.empty ());
|
|
196
|
+
htrs--;
|
|
197
|
+
if (hyper_ternary_resolve (c, pivot, d)) {
|
|
198
|
+
size_t size = clause.size ();
|
|
199
|
+
bool red = (size == 3 || (c->redundant && d->redundant));
|
|
200
|
+
if (lrat) {
|
|
201
|
+
assert (lrat_chain.empty ());
|
|
202
|
+
lrat_chain.push_back (c->id);
|
|
203
|
+
lrat_chain.push_back (d->id);
|
|
204
|
+
}
|
|
205
|
+
Clause *r = new_hyper_ternary_resolved_clause (red);
|
|
206
|
+
if (red)
|
|
207
|
+
r->hyper = true;
|
|
208
|
+
lrat_chain.clear ();
|
|
209
|
+
clause.clear ();
|
|
210
|
+
LOG (r, "hyper ternary resolved");
|
|
211
|
+
stats.htrs++;
|
|
212
|
+
for (const auto &lit : *r)
|
|
213
|
+
occs (lit).push_back (r);
|
|
214
|
+
if (size == 2) {
|
|
215
|
+
LOG ("hyper ternary resolvent subsumes both antecedents");
|
|
216
|
+
mark_garbage (c);
|
|
217
|
+
mark_garbage (d);
|
|
218
|
+
stats.htrs2++;
|
|
219
|
+
break;
|
|
220
|
+
} else {
|
|
221
|
+
assert (r->size == 3);
|
|
222
|
+
stats.htrs3++;
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
LOG (clause, "ignoring size %zd resolvent", clause.size ());
|
|
226
|
+
clause.clear ();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/*------------------------------------------------------------------------*/
|
|
233
|
+
|
|
234
|
+
// Same as 'ternary_lit' but pick the phase of the variable based on the
|
|
235
|
+
// number of positive and negative occurrence.
|
|
236
|
+
|
|
237
|
+
void Internal::ternary_idx (int idx, int64_t &steps, int64_t &htrs) {
|
|
238
|
+
assert (0 < idx);
|
|
239
|
+
assert (idx <= max_var);
|
|
240
|
+
steps -= 3;
|
|
241
|
+
if (!active (idx))
|
|
242
|
+
return;
|
|
243
|
+
if (!flags (idx).ternary)
|
|
244
|
+
return;
|
|
245
|
+
int pos = occs (idx).size ();
|
|
246
|
+
int neg = occs (-idx).size ();
|
|
247
|
+
if (pos <= opts.ternaryocclim && neg <= opts.ternaryocclim) {
|
|
248
|
+
LOG ("index %d has %zd positive and %zd negative occurrences", idx,
|
|
249
|
+
occs (idx).size (), occs (-idx).size ());
|
|
250
|
+
int pivot = (neg < pos ? -idx : idx);
|
|
251
|
+
ternary_lit (pivot, steps, htrs);
|
|
252
|
+
}
|
|
253
|
+
flags (idx).ternary = false;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/*------------------------------------------------------------------------*/
|
|
257
|
+
|
|
258
|
+
// One round of ternary resolution over all variables. As in 'block' and
|
|
259
|
+
// 'elim' we maintain a persistent global flag 'ternary' for each variable,
|
|
260
|
+
// which records, whether a ternary clause containing it was added. Then we
|
|
261
|
+
// can focus on those variables for which we have not tried ternary
|
|
262
|
+
// resolution before and nothing changed for them since then. This works
|
|
263
|
+
// across multiple calls to 'ternary' as well as 'ternary_round' since this
|
|
264
|
+
// 'ternary' variable flag is updated during adding (ternary) resolvents.
|
|
265
|
+
// This function goes over each variable just once.
|
|
266
|
+
|
|
267
|
+
bool Internal::ternary_round (int64_t &steps_limit, int64_t &htrs_limit) {
|
|
268
|
+
|
|
269
|
+
assert (!unsat);
|
|
270
|
+
|
|
271
|
+
#ifndef QUIET
|
|
272
|
+
int64_t bincon = 0;
|
|
273
|
+
int64_t terncon = 0;
|
|
274
|
+
#endif
|
|
275
|
+
|
|
276
|
+
init_occs ();
|
|
277
|
+
|
|
278
|
+
steps_limit -= 1 + cache_lines (clauses.size (), sizeof (Clause *));
|
|
279
|
+
for (const auto &c : clauses) {
|
|
280
|
+
steps_limit--;
|
|
281
|
+
if (c->garbage)
|
|
282
|
+
continue;
|
|
283
|
+
if (c->size > 3)
|
|
284
|
+
continue;
|
|
285
|
+
bool assigned = false, marked = false;
|
|
286
|
+
for (const auto &lit : *c) {
|
|
287
|
+
if (val (lit)) {
|
|
288
|
+
assigned = true;
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
if (flags (lit).ternary)
|
|
292
|
+
marked = true;
|
|
293
|
+
}
|
|
294
|
+
if (assigned)
|
|
295
|
+
continue;
|
|
296
|
+
if (c->size == 2) {
|
|
297
|
+
#ifndef QUIET
|
|
298
|
+
bincon++;
|
|
299
|
+
#endif
|
|
300
|
+
} else {
|
|
301
|
+
assert (c->size == 3);
|
|
302
|
+
if (!marked)
|
|
303
|
+
continue;
|
|
304
|
+
#ifndef QUIET
|
|
305
|
+
terncon++;
|
|
306
|
+
#endif
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
for (const auto &lit : *c)
|
|
310
|
+
occs (lit).push_back (c);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
PHASE ("ternary", stats.ternary,
|
|
314
|
+
"connected %" PRId64 " ternary %.0f%% "
|
|
315
|
+
"and %" PRId64 " binary clauses %.0f%%",
|
|
316
|
+
terncon, percent (terncon, clauses.size ()), bincon,
|
|
317
|
+
percent (bincon, clauses.size ()));
|
|
318
|
+
|
|
319
|
+
// Try ternary resolution on all variables once.
|
|
320
|
+
//
|
|
321
|
+
for (auto idx : vars) {
|
|
322
|
+
if (terminated_asynchronously ())
|
|
323
|
+
break;
|
|
324
|
+
if (steps_limit < 0)
|
|
325
|
+
break;
|
|
326
|
+
if (htrs_limit < 0)
|
|
327
|
+
break;
|
|
328
|
+
ternary_idx (idx, steps_limit, htrs_limit);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Gather some statistics for the verbose messages below and also
|
|
332
|
+
// determine whether new variables have been marked and it would make
|
|
333
|
+
// sense to run another round of ternary resolution over those variables.
|
|
334
|
+
//
|
|
335
|
+
int remain = 0;
|
|
336
|
+
for (auto idx : vars) {
|
|
337
|
+
if (!active (idx))
|
|
338
|
+
continue;
|
|
339
|
+
if (!flags (idx).ternary)
|
|
340
|
+
continue;
|
|
341
|
+
remain++;
|
|
342
|
+
}
|
|
343
|
+
if (remain)
|
|
344
|
+
PHASE ("ternary", stats.ternary, "%d variables remain %.0f%%", remain,
|
|
345
|
+
percent (remain, max_var));
|
|
346
|
+
else
|
|
347
|
+
PHASE ("ternary", stats.ternary, "completed hyper ternary resolution");
|
|
348
|
+
|
|
349
|
+
reset_occs ();
|
|
350
|
+
assert (!unsat);
|
|
351
|
+
|
|
352
|
+
return remain; // Are there variables that should be tried again?
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/*------------------------------------------------------------------------*/
|
|
356
|
+
|
|
357
|
+
bool Internal::ternary () {
|
|
358
|
+
|
|
359
|
+
if (!opts.ternary)
|
|
360
|
+
return false;
|
|
361
|
+
if (unsat)
|
|
362
|
+
return false;
|
|
363
|
+
if (terminated_asynchronously ())
|
|
364
|
+
return false;
|
|
365
|
+
|
|
366
|
+
// No new ternary clauses added since last time?
|
|
367
|
+
//
|
|
368
|
+
if (last.ternary.marked == stats.mark.ternary)
|
|
369
|
+
return false;
|
|
370
|
+
|
|
371
|
+
SET_EFFORT_LIMIT (limit, ternary, true);
|
|
372
|
+
|
|
373
|
+
START_SIMPLIFIER (ternary, TERNARY);
|
|
374
|
+
stats.ternary++;
|
|
375
|
+
|
|
376
|
+
assert (!level);
|
|
377
|
+
|
|
378
|
+
assert (!unsat);
|
|
379
|
+
if (watching ())
|
|
380
|
+
reset_watches ();
|
|
381
|
+
|
|
382
|
+
// The number of clauses derived through ternary resolution can grow
|
|
383
|
+
// substantially, particularly for random formulas. Thus we limit the
|
|
384
|
+
// number of added clauses too (actually the number of 'htrs').
|
|
385
|
+
//
|
|
386
|
+
int64_t htrs_limit = stats.current.redundant + stats.current.irredundant;
|
|
387
|
+
htrs_limit *= opts.ternarymaxadd;
|
|
388
|
+
htrs_limit /= 100;
|
|
389
|
+
|
|
390
|
+
// approximation of ternary ticks.
|
|
391
|
+
// TODO: count with ternary.ticks directly.
|
|
392
|
+
int64_t steps_limit = stats.ticks.ternary - limit;
|
|
393
|
+
stats.ticks.ternary = limit;
|
|
394
|
+
|
|
395
|
+
// With 'stats.ternary' we actually count the number of calls to
|
|
396
|
+
// 'ternary_round' and not the number of calls to 'ternary'. But before
|
|
397
|
+
// the first round we want to show the limit on the number of steps and
|
|
398
|
+
// thus we increase counter for the first round here and skip increasing
|
|
399
|
+
// it in the loop below.
|
|
400
|
+
//
|
|
401
|
+
PHASE ("ternary", stats.ternary,
|
|
402
|
+
"will run a maximum of %d rounds "
|
|
403
|
+
"limited to %" PRId64 " steps and %" PRId64 " clauses",
|
|
404
|
+
opts.ternaryrounds, steps_limit, htrs_limit);
|
|
405
|
+
|
|
406
|
+
bool resolved_binary_clause = false;
|
|
407
|
+
bool completed = false;
|
|
408
|
+
|
|
409
|
+
for (int round = 0;
|
|
410
|
+
!terminated_asynchronously () && round < opts.ternaryrounds;
|
|
411
|
+
round++) {
|
|
412
|
+
if (htrs_limit < 0)
|
|
413
|
+
break;
|
|
414
|
+
if (steps_limit < 0)
|
|
415
|
+
break;
|
|
416
|
+
if (round)
|
|
417
|
+
stats.ternary++;
|
|
418
|
+
int old_htrs2 = stats.htrs2;
|
|
419
|
+
int old_htrs3 = stats.htrs3;
|
|
420
|
+
completed = ternary_round (steps_limit, htrs_limit);
|
|
421
|
+
int delta_htrs2 = stats.htrs2 - old_htrs2;
|
|
422
|
+
int delta_htrs3 = stats.htrs3 - old_htrs3;
|
|
423
|
+
PHASE ("ternary", stats.ternary,
|
|
424
|
+
"derived %d ternary and %d binary resolvents", delta_htrs3,
|
|
425
|
+
delta_htrs2);
|
|
426
|
+
report ('3', !opts.reportall && !(delta_htrs2 + delta_htrs2));
|
|
427
|
+
if (delta_htrs2)
|
|
428
|
+
resolved_binary_clause = true;
|
|
429
|
+
if (!delta_htrs3)
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
assert (!occurring ());
|
|
434
|
+
assert (!unsat);
|
|
435
|
+
init_watches ();
|
|
436
|
+
connect_watches ();
|
|
437
|
+
if (!propagate ()) {
|
|
438
|
+
LOG ("propagation after connecting watches results in inconsistency");
|
|
439
|
+
learn_empty_clause ();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (completed)
|
|
443
|
+
last.ternary.marked = stats.mark.ternary;
|
|
444
|
+
|
|
445
|
+
STOP_SIMPLIFIER (ternary, TERNARY);
|
|
446
|
+
|
|
447
|
+
return resolved_binary_clause;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
} // namespace CaDiCaL
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#ifndef _testing_hpp_INCLUDED
|
|
2
|
+
#define _testing_hpp_INCLUDED
|
|
3
|
+
|
|
4
|
+
// This class provides access to 'internal' which should only be used for
|
|
5
|
+
// internal testing and not for any other purpose as 'internal' is supposed
|
|
6
|
+
// to be hidden.
|
|
7
|
+
|
|
8
|
+
#include "cadical.hpp"
|
|
9
|
+
|
|
10
|
+
namespace CaDiCaL {
|
|
11
|
+
|
|
12
|
+
class Testing {
|
|
13
|
+
Solver *solver;
|
|
14
|
+
|
|
15
|
+
public:
|
|
16
|
+
Testing (Solver &s) : solver (&s) {}
|
|
17
|
+
Testing (Solver *s) : solver (s) {}
|
|
18
|
+
Internal *internal () { return solver->internal; }
|
|
19
|
+
External *external () { return solver->external; }
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
} // namespace CaDiCaL
|
|
23
|
+
|
|
24
|
+
#endif
|