Skip to content

Commit e065fbb

Browse files
committed
Trying example blocking lit
Fixing seen cleaning Fixing off by one Fixing for vars already set Better example generation Graph Allow command line control, better printing Guard against unsat Go through lits randomly Fixing printing Step-out for blocking clause searching Use SLOW_DEBUG_DO Cleaner code Randomize lit to take This means it will be more likely to be removed. When looking at another lit, another time.
1 parent f506278 commit e065fbb

File tree

5 files changed

+233
-8
lines changed

5 files changed

+233
-8
lines changed

scripts/data/create_graphs_ganak.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,13 @@ def get_dirs(ver : str):
476476
# "out-ganak-mc2324-14195954-0",
477477

478478
# complex numbers from Mei
479-
"out-ganak-gpmc-mei-14294765-", # gpmc
479+
# "out-ganak-gpmc-mei-14294765-", # gpmc
480480
# "out-ganak-gpmc-mei-14295250-0", # ganak, fixed complex
481-
"out-ganak-gpmc-mei-14295899-0", # mpfr ganak
481+
# "out-ganak-gpmc-mei-14295899-0", # mpfr ganak
482+
483+
# parity
484+
"out-ganak-gpmc-parity-14296246-", # parity
485+
"out-ganak-gpmc-parity-14298930-", # parity
482486
]
483487
# only_dirs = ["out-ganak-6828273"] #-- functional synth
484488
#"6393432", "6393432", "6349002",, "6349002", "6387743" "6356951"] #, "out-ganak-6318929.pbs101-4", "out-ganak-6328707.pbs101-7", "out-ganak-6318929.pbs101-7"] #,"6348728" "6346880", "6335522", "6328982", "6328707"]
@@ -655,7 +659,7 @@ def get_dirs(ver : str):
655659
f.write("set ylabel \"Instances counted\"\n")
656660
f.write("set xlabel \"Time (s)\"\n")
657661
# f.write("plot [:][10:]\\\n")
658-
f.write("plot [:][900:]\\\n")
662+
f.write("plot [:][:]\\\n")
659663
i = 0
660664
# f.write(" \"runkcbox-prearjun.csv.gnuplotdata\" u 2:1 with linespoints title \"KCBox\",\\\n")
661665
# f.write(" \"runsharptd-prearjun.csv.gnuplotdata\" u 2:1 with linespoints title \"SharptTD\",\\\n")

src/comp_analyzer.cpp

Lines changed: 218 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,207 @@ inline std::ostream& operator<<(std::ostream& os, const ClData& d)
4040
return os;
4141
}
4242

43+
void CompAnalyzer::calc_blocked(
44+
const LiteralIndexedVector<LitWatchList> & watches,
45+
const ClauseAllocator* alloc, const vector<ClauseOfs>& long_irred_cls)
46+
{
47+
const uint32_t n = max_var+1;
48+
clid_to_blocking_lits.resize(long_irred_cls.size()+1);
49+
if (!conf.do_blocked_clauses) return;
50+
51+
if (counter->get_opt_indep_support_end() >= max_var+1) {
52+
verb_print(1, "No need to calculate blocked clauses, as all vars are opt independent");
53+
return;
54+
}
55+
const double start_time = cpu_time();
56+
57+
// build occ lists
58+
vector<vector<Lit>> id_to_cl;
59+
vector<vector<uint32_t>> occs;
60+
occs.resize(n*2);
61+
uint32_t clid_bin_start;
62+
63+
if (true) {
64+
uint32_t clid = 1;
65+
id_to_cl.resize(1);
66+
vector<Lit> tmp;
67+
for (const auto& off: long_irred_cls) {
68+
const Clause& cl = *alloc->ptr(off);
69+
assert(cl.size() > 2);
70+
tmp.clear();
71+
tmp.insert(tmp.end(), cl.begin(), cl.end());
72+
for(const auto& l: cl) occs[l.raw()].push_back(clid);
73+
id_to_cl.push_back(tmp);
74+
assert(id_to_cl.size()-1 == clid);
75+
clid++;
76+
}
77+
clid_bin_start = clid;
78+
79+
for (uint32_t v = 1; v < n; v++) {
80+
for(uint32_t i = 0; i < 2; i++) {
81+
Lit l(v, i);
82+
for (const auto& bincl: watches[l].binaries) {
83+
if (bincl.irred()) {
84+
tmp.clear();
85+
tmp.push_back(l);
86+
tmp.push_back(bincl.lit());
87+
occs[tmp[0].raw()].push_back(clid);
88+
occs[tmp[1].raw()].push_back(clid);
89+
id_to_cl.push_back(tmp);
90+
assert(id_to_cl.size()-1 == clid);
91+
clid++;
92+
}
93+
}
94+
}
95+
}
96+
}
97+
98+
// System below does NOT work if any literal is already set
99+
// This is guaranteed to be NOT BAD if arjun is run before
100+
bool bad = false;
101+
for (uint32_t v = 1; v < n; v++) {
102+
for(uint32_t i = 0; i < 2; i++) {
103+
Lit l(v, i);
104+
if (!is_unknown(l)) bad = true;
105+
}
106+
}
107+
if (bad) {
108+
verb_print(1, "Some vars are not unknown, cannot calculate blocked clauses");
109+
return;
110+
}
111+
112+
uint32_t blocked_tot = 0;
113+
vector<char> seen(n*2, 0);
114+
vector<char> seen_set(n*2, 0);
115+
vector<Lit> seen_set_clear;
116+
vector<Lit> todo_lits;
117+
for (uint32_t v = 1; v < n; v++) for(uint32_t i = 0; i < 2; i++) todo_lits.push_back(Lit(v, i));
118+
std::shuffle(todo_lits.begin(), todo_lits.end(), mtrand);
119+
120+
int64_t todo_total = 400*1000LL*1000LL;
121+
uint32_t lit_abandoned = 0;
122+
for (const auto& l_set: todo_lits) {
123+
int64_t todo_per_lit = 1000*1000LL;
124+
if (todo_total <= 0) break;
125+
bool unsat = false;
126+
/* cout << "lit set: " << l_set << endl; */
127+
vector<Lit> prop_q;
128+
prop_q.push_back(l_set);
129+
// slow propagation..
130+
SLOW_DEBUG_DO(for(const auto& l: seen_set) assert(l == 0));
131+
while(!prop_q.empty()) {
132+
Lit p = prop_q.back();
133+
seen_set[p.raw()] = 1;
134+
seen_set_clear.push_back(p);
135+
prop_q.pop_back();
136+
for(const auto& cl_id: occs[l_set.neg().raw()]) {
137+
const auto& cl = id_to_cl[cl_id];
138+
bool sat = false;
139+
uint32_t unk = 0;
140+
Lit lit_unk = Lit();
141+
for(const auto& l: cl) {
142+
todo_per_lit--;
143+
todo_total--;
144+
if (seen_set[l.raw()]) {
145+
sat = 1;
146+
break;
147+
}
148+
if (seen[l.neg().raw()]) continue;
149+
unk++;
150+
lit_unk = l;
151+
if (unk > 1) break;
152+
}
153+
if (!sat && unk == 0) {
154+
// wow, unsat
155+
unsat = true;
156+
return;
157+
}
158+
if (sat) continue;
159+
if (unk == 1) prop_q.push_back(lit_unk);
160+
}
161+
}
162+
if (unsat) goto next;
163+
164+
for(uint32_t clid = 1; clid < clid_bin_start; clid++) {
165+
if (todo_per_lit <= 0) {lit_abandoned++; goto next;}
166+
const auto& cl = id_to_cl[clid];
167+
assert(cl.size() > 2);
168+
169+
// already satisfied
170+
bool sat_already = false;
171+
for(const auto& l: cl) if (seen_set[l.raw()]) {
172+
sat_already = true;
173+
break;
174+
}
175+
if (sat_already) continue;
176+
177+
// cannot actually be blocked
178+
bool could_be_blocked = false;
179+
for(const auto& l: cl) if (l.var() >= counter->get_opt_indep_support_end()) {
180+
could_be_blocked = true;
181+
break;
182+
}
183+
if (!could_be_blocked) continue;
184+
/* cout << "cl to block: " << cl << endl; */
185+
186+
bool blocked = false;
187+
SLOW_DEBUG_DO(for(const auto& l: seen) assert(l == 0));
188+
for(const auto& l: cl) seen[l.raw()] = 1;
189+
for(const auto& l: cl) if (l.var() >= counter->get_opt_indep_support_end()) {
190+
// could be blocked on this var, i.e. l.var()
191+
// must be blocked relative to all other clauses it could be resolved with
192+
blocked = true;
193+
for(const auto& clid2: occs[l.neg().raw()]) {
194+
bool blocked_rel_this = false;
195+
const auto& cl2 = id_to_cl[clid2];
196+
for(const auto& l2: cl2) {
197+
todo_per_lit--;
198+
todo_total--;
199+
if (l2.neg() == l) continue; // resolve on this, skip
200+
/* if (seen[l2.neg().raw()]) { */
201+
if (seen_set[l2.raw()]|| seen[l2.neg().raw()]) {
202+
/* cout << "blocked with cl2 " << cl2 << " on: " << l2
203+
* << " -- actually, set instead? " << (int)(l2 == l_set) << endl; */
204+
blocked_rel_this = true;
205+
break;
206+
}
207+
}
208+
if (!blocked_rel_this) {
209+
blocked = false;
210+
break;
211+
}
212+
}
213+
if (!blocked) continue; // try next var
214+
if (blocked) {
215+
/* cout << "BINGO! cl: " << cl << " blocked on: " << l << " given: " << l_set << endl; */
216+
clid_to_blocking_lits[clid].push_back(l_set);
217+
blocked_tot++;
218+
break;
219+
}
220+
}
221+
for(const auto& l: cl) seen[l.raw()] = 0;
222+
}
223+
224+
next:
225+
for(const auto& l: seen_set_clear) seen_set[l.raw()] = 0;
226+
seen_set_clear.clear();
227+
}
228+
229+
uint32_t cls_blocked = 0;
230+
for(auto& lits: clid_to_blocking_lits) {
231+
if (!lits.empty()) cls_blocked++;
232+
std::shuffle(lits.begin(), lits.end(), mtrand);
233+
}
234+
235+
verb_print(1, "Blocked tot: " << blocked_tot
236+
<< " lits abandoned: " << lit_abandoned << " global t-out: " << (todo_total <= 0)
237+
<< " t-remain: " << (double)todo_total/(1000.0*1000.0) << "M"
238+
<< " avg blocked/lit: " << (double)blocked_tot/(double)(n*2-2) << " T: " << cpu_time()-start_time);
239+
verb_print(1, "cls with blocked lits: " << cls_blocked << " / " << long_irred_cls.size()
240+
<< " = " << (double)cls_blocked/(double)long_irred_cls.size()*100 << "%");
241+
242+
}
243+
43244
// Builds occ lists and sets things up, Done exactly ONCE for a whole counting runkk
44245
// this sets up unif_occ
45246
void CompAnalyzer::initialize(
@@ -60,7 +261,8 @@ void CompAnalyzer::initialize(
60261
return a.size() < b.size();
61262
};
62263
auto long_irred_cls = _long_irred_cls;
63-
std::sort(long_irred_cls.begin(), long_irred_cls.end(), mysorter);
264+
std::stable_sort(long_irred_cls.begin(), long_irred_cls.end(), mysorter);
265+
calc_blocked(watches, alloc, long_irred_cls);
64266

65267
max_clid = 1;
66268
max_tri_clid = 1;
@@ -74,17 +276,18 @@ void CompAnalyzer::initialize(
74276
const Clause& cl = *alloc->ptr(off);
75277
assert(cl.size() > 2);
76278
const uint32_t long_cl_off = long_clauses_data.size();
279+
77280
if (cl.size() > 3) {
78281
Lit blk_lit = cl[cl.size()/2];
79282
for(const auto&l: cl) long_clauses_data.push_back(l);
80283
long_clauses_data.push_back(SENTINEL_LIT);
81-
82284
for(const auto& l: cl) {
83285
const uint32_t var = l.var();
84286
assert(var < n);
85287
ClData d;
86288
d.id = max_clid;
87289
d.blk_lit = blk_lit;
290+
d.example_blocking = NOT_A_LIT;
88291
d.off = long_cl_off;
89292
unif_occ_long[var].push_back(d);
90293
}
@@ -98,6 +301,7 @@ void CompAnalyzer::initialize(
98301
ClData d;
99302
d.id = max_clid;
100303
d.blk_lit = lits[0];
304+
d.example_blocking = NOT_A_LIT;
101305
d.off = lits[1].raw();
102306
unif_occ_long[l.var()].push_back(d);
103307
}
@@ -183,11 +387,17 @@ void CompAnalyzer::initialize(
183387
}
184388
}
185389

186-
// check longs
390+
// check longs & adjust blocking lits to random ones
187391
for(uint32_t v = 0; v < unif_occ_long.size(); v++) {
188392
assert(unif_occ_long[v].size() == holder.size_long(v));
189393
for(uint32_t i = 0; i < unif_occ_long[v].size(); i++) {
190394
assert(unif_occ_long[v][i] == holder.begin_long(v)[i]);
395+
auto& d = holder.begin_long(v)[i];
396+
auto& blk_lits = clid_to_blocking_lits[d.id];
397+
if (!blk_lits.empty()) {
398+
std::uniform_int_distribution<uint32_t> dist(0, blk_lits.size()-1);
399+
d.example_blocking = blk_lits[dist(mtrand)];
400+
}
191401
}
192402
}
193403
}
@@ -342,7 +552,8 @@ void CompAnalyzer::record_comp(const uint32_t var, const uint32_t sup_comp_long_
342552
if (archetype.clause_unvisited_in_sup_comp(d.id)) {
343553
const Lit l1 = d.get_lit1();
344554
const Lit l2 = d.get_lit2();
345-
if (is_true(l1) || is_true(l2)) {
555+
if (is_true(l1) || is_true(l2) ||
556+
(d.example_blocking != NOT_A_LIT && is_true(d.example_blocking))) {
346557
archetype.clear_cl(d.id);
347558
sat = true;
348559
/* goto end_sat; */
@@ -355,7 +566,8 @@ void CompAnalyzer::record_comp(const uint32_t var, const uint32_t sup_comp_long_
355566
} else continue;
356567
} else {
357568
if (archetype.clause_unvisited_in_sup_comp(d.id)) {
358-
if (is_true(d.blk_lit)) {
569+
if (is_true(d.blk_lit) ||
570+
(d.example_blocking != NOT_A_LIT && is_true(d.example_blocking))) {
359571
archetype.clear_cl(d.id);
360572
sat = true;
361573
goto end_sat;
@@ -393,6 +605,7 @@ end_sat:;
393605
CompAnalyzer::CompAnalyzer(
394606
const LiteralIndexedVector<TriValue> & lit_values,
395607
Counter* _counter) :
608+
mtrand(_counter->get_conf().seed),
396609
values(lit_values),
397610
conf(_counter->get_conf()),
398611
indep_support_end(_counter->get_indep_support_end()),

src/comp_analyzer.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct ClData {
5252
uint32_t id;
5353
uint32_t off;
5454
Lit blk_lit;
55+
Lit example_blocking = NOT_A_LIT;
5556
bool operator==(const ClData& other) const {
5657
return id == other.id && off == other.off && blk_lit == other.blk_lit;
5758
}
@@ -178,6 +179,11 @@ class CompAnalyzer {
178179
CompArchetype& get_archetype() { return archetype; }
179180

180181
private:
182+
void calc_blocked(const LiteralIndexedVector<LitWatchList> & literals,
183+
const ClauseAllocator* alloc, const vector<ClauseOfs>& long_irred_cls);
184+
vector<vector<Lit>> clid_to_blocking_lits;
185+
std::mt19937_64 mtrand;
186+
181187
// the id of the last clause
182188
// note that clause ID is the clause number,
183189
// different from the offset of the clause in the literal pool

src/counter_config.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct CounterConfiguration {
4040
int max_num_rst = -1;
4141
uint32_t lbd_cutoff_always_keep_cube = 3;
4242
uint32_t max_num_cubes_per_restart = 6;
43+
int do_blocked_clauses = 1;
4344

4445
int cache_time_update = 2;
4546

src/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ void add_ganak_options()
132132
myopt("--appmct", conf.appmc_timeout, atof, "after K seconds");
133133
myopt("--epsilon", conf.appmc_epsilon, atof, "AppMC epsilon");
134134
myopt("--chronobt", conf.do_chronobt, atof, "ChronoBT. SAT must be DISABLED or this will fail");
135+
myopt("--blocked", conf.do_blocked_clauses, atof, "Blocked clauses, semi-dynamic, with example lit");
135136
//
136137
// Arjun options
137138
myopt("--arjun", do_arjun, atoi, "Use arjun");

0 commit comments

Comments
 (0)