Skip to content

Commit 4c9ede1

Browse files
committed
Trying example blocking lit
1 parent f506278 commit 4c9ede1

File tree

2 files changed

+185
-4
lines changed

2 files changed

+185
-4
lines changed

src/comp_analyzer.cpp

Lines changed: 180 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ THE SOFTWARE.
3030
#include <cstdint>
3131
#include <cstdint>
3232
#include <memory>
33+
#include <ratio>
3334

3435
using namespace GanakInt;
3536

@@ -40,6 +41,160 @@ inline std::ostream& operator<<(std::ostream& os, const ClData& d)
4041
return os;
4142
}
4243

44+
void CompAnalyzer::calc_blocked(
45+
const LiteralIndexedVector<LitWatchList> & watches,
46+
const ClauseAllocator* alloc, const vector<ClauseOfs>& long_irred_cls)
47+
{
48+
const uint32_t n = max_var+1;
49+
lit_to_blocked_clids.resize(n*2);
50+
if (counter->get_opt_indep_support_end() >= max_var+1) {
51+
verb_print(1, "No need to calculate blocked clauses, as all vars are opt independent");
52+
return;
53+
}
54+
const double start_time = cpu_time();
55+
56+
// build occ lists
57+
vector<vector<Lit>> id_to_cl;
58+
vector<vector<uint32_t>> occs;
59+
occs.resize(n*2);
60+
uint32_t clid_bin_start;
61+
62+
if (true) {
63+
uint32_t clid = 1;
64+
id_to_cl.resize(1);
65+
vector<Lit> tmp;
66+
for (const auto& off: long_irred_cls) {
67+
const Clause& cl = *alloc->ptr(off);
68+
assert(cl.size() > 2);
69+
tmp.clear();
70+
tmp.insert(tmp.end(), cl.begin(), cl.end());
71+
for(const auto& l: cl) occs[l.raw()].push_back(clid);
72+
id_to_cl.push_back(tmp);
73+
assert(id_to_cl.size()-1 == clid);
74+
clid++;
75+
}
76+
clid_bin_start = clid;
77+
78+
for (uint32_t v = 1; v < n; v++) {
79+
for(uint32_t i = 0; i < 2; i++) {
80+
Lit l(v, i);
81+
for (const auto& bincl: watches[l].binaries) {
82+
if (bincl.irred()) {
83+
tmp.clear();
84+
tmp.push_back(l);
85+
tmp.push_back(bincl.lit());
86+
occs[tmp[0].raw()].push_back(clid);
87+
occs[tmp[1].raw()].push_back(clid);
88+
id_to_cl.push_back(tmp);
89+
assert(id_to_cl.size()-1 == clid);
90+
clid++;
91+
}
92+
}
93+
}
94+
}
95+
}
96+
97+
uint32_t blocked_tot = 0;
98+
vector<char> seen(n*2, 0);
99+
vector<char> seen_set(n*2, 0);
100+
vector<Lit> seed_set_clear;
101+
for (uint32_t v = 1; v < n; v++) {
102+
for(uint32_t i = 0; i < 2; i++) {
103+
vector<uint32_t> clids_blocked;
104+
Lit l_set(v, i);
105+
cout << "lit set: " << l_set << endl;
106+
vector<Lit> prop_q;
107+
prop_q.push_back(l_set);
108+
// slow propagation..
109+
/* SLOW_DEBUG_DO(for(const auto& l: seen_set) assert(l == 0)); */
110+
for(const auto& l: seen_set) assert(l == 0);
111+
while(!prop_q.empty()) {
112+
Lit p = prop_q.back();
113+
seen_set[p.raw()] = 1;
114+
seed_set_clear.push_back(p);
115+
prop_q.pop_back();
116+
for(const auto& cl_id: occs[l_set.neg().raw()]) {
117+
const auto& cl = id_to_cl[cl_id];
118+
bool sat = false;
119+
uint32_t unk = 0;
120+
Lit lit_unk = Lit();
121+
for(const auto& l: cl) {
122+
if (seen_set[l.raw()]) {
123+
sat = 1;
124+
break;
125+
}
126+
if (seen[l.neg().raw()]) continue;
127+
unk++;
128+
lit_unk = l;
129+
if (unk > 1) break;
130+
}
131+
if (sat) continue;
132+
if (unk == 1) prop_q.push_back(lit_unk);
133+
}
134+
}
135+
136+
for(uint32_t clid = 1; clid < clid_bin_start; clid++) {
137+
const auto& cl = id_to_cl[clid-1];
138+
139+
// already satisfied
140+
bool sat_already = false;
141+
for(const auto& l: cl) if (seen_set[l.raw()]) {
142+
sat_already = true;
143+
break;
144+
}
145+
if (sat_already) continue;
146+
147+
// cannot actually be blocked
148+
bool could_be_blocked = false;
149+
for(const auto& l: cl) if (l.var() >= counter->get_opt_indep_support_end()) {
150+
could_be_blocked = true;
151+
break;
152+
}
153+
if (!could_be_blocked) continue;
154+
/* cout << "cl to block: " << cl << endl; */
155+
156+
bool blocked = false;
157+
/* SLOW_DEBUG_DO(for(const auto& l: seen) assert(l == 0)); */
158+
for(const auto& l: seen) assert(l == 0);
159+
for(const auto& l: cl) seen[l.raw()] = 1;
160+
for(const auto& l: cl) if (l.var() >= counter->get_opt_indep_support_end()) {
161+
// could be blocked on this var
162+
// must be blocked relative to all other clauses it could be resolved with
163+
blocked = true;
164+
for(const auto& clid2: occs[l.neg().raw()]) {
165+
bool blocked_rel_this = false;
166+
const auto& cl2 = id_to_cl[clid2];
167+
for(const auto& l2: cl2) {
168+
if (l2.neg() == l) continue; // resolve on this, skip
169+
if (seen_set[l2.raw()]|| seen[l2.neg().raw()]) { //satisfied or blocked
170+
/* cout << "blocked with cl2 " << cl2 << " on: " << l2 << " -- actually, set instead? " << (int)(l2 == l_set) << endl; */
171+
blocked_rel_this = true;
172+
break;
173+
}
174+
}
175+
if (!blocked_rel_this) {
176+
blocked = false;
177+
break;
178+
}
179+
}
180+
if (!blocked) continue; // try next var
181+
if (blocked) {
182+
cout << "BINGO! cl: " << cl << " blocked on: " << l << " given: " << l_set << endl;
183+
clids_blocked.push_back(clid);
184+
break;
185+
}
186+
}
187+
for(const auto& l: cl) seen[l.raw()] = 0;
188+
}
189+
190+
blocked_tot += clids_blocked.size();
191+
lit_to_blocked_clids[l_set.raw()] = clids_blocked;
192+
}
193+
for(const auto& l: seed_set_clear) seen_set[l.raw()] = 0;
194+
}
195+
verb_print(1, "Blocked tot: " << blocked_tot << " avg: " << (double)blocked_tot/(double)(n*2-2) << " T: " << cpu_time()-start_time);
196+
}
197+
43198
// Builds occ lists and sets things up, Done exactly ONCE for a whole counting runkk
44199
// this sets up unif_occ
45200
void CompAnalyzer::initialize(
@@ -60,7 +215,8 @@ void CompAnalyzer::initialize(
60215
return a.size() < b.size();
61216
};
62217
auto long_irred_cls = _long_irred_cls;
63-
std::sort(long_irred_cls.begin(), long_irred_cls.end(), mysorter);
218+
std::stable_sort(long_irred_cls.begin(), long_irred_cls.end(), mysorter);
219+
calc_blocked(watches, alloc, long_irred_cls);
64220

65221
max_clid = 1;
66222
max_tri_clid = 1;
@@ -74,17 +230,34 @@ void CompAnalyzer::initialize(
74230
const Clause& cl = *alloc->ptr(off);
75231
assert(cl.size() > 2);
76232
const uint32_t long_cl_off = long_clauses_data.size();
233+
234+
Lit example_blocking = NOT_A_LIT;
235+
bool found = false;
236+
for (int32_t v = n-1; v >= 1; v--) {
237+
for(uint32_t i2 = 0; i2 < 2; i2++) {
238+
Lit b = Lit(v, i2);
239+
const auto& list = lit_to_blocked_clids[b.raw()];
240+
if (std::find(list.begin(), list.end(), max_clid) != list.end()) {
241+
example_blocking = b;
242+
cout << "Example blocking: " << example_blocking << " for cl: " << cl << " id: " << max_clid << endl;
243+
found = true;
244+
break;
245+
}
246+
}
247+
if (found) break;
248+
}
249+
77250
if (cl.size() > 3) {
78251
Lit blk_lit = cl[cl.size()/2];
79252
for(const auto&l: cl) long_clauses_data.push_back(l);
80253
long_clauses_data.push_back(SENTINEL_LIT);
81-
82254
for(const auto& l: cl) {
83255
const uint32_t var = l.var();
84256
assert(var < n);
85257
ClData d;
86258
d.id = max_clid;
87259
d.blk_lit = blk_lit;
260+
d.example_blocking = example_blocking;
88261
d.off = long_cl_off;
89262
unif_occ_long[var].push_back(d);
90263
}
@@ -98,6 +271,7 @@ void CompAnalyzer::initialize(
98271
ClData d;
99272
d.id = max_clid;
100273
d.blk_lit = lits[0];
274+
d.example_blocking = example_blocking;
101275
d.off = lits[1].raw();
102276
unif_occ_long[l.var()].push_back(d);
103277
}
@@ -342,7 +516,8 @@ void CompAnalyzer::record_comp(const uint32_t var, const uint32_t sup_comp_long_
342516
if (archetype.clause_unvisited_in_sup_comp(d.id)) {
343517
const Lit l1 = d.get_lit1();
344518
const Lit l2 = d.get_lit2();
345-
if (is_true(l1) || is_true(l2)) {
519+
if (is_true(l1) || is_true(l2) ||
520+
(d.example_blocking != NOT_A_LIT && is_true(d.example_blocking))) {
346521
archetype.clear_cl(d.id);
347522
sat = true;
348523
/* goto end_sat; */
@@ -355,7 +530,8 @@ void CompAnalyzer::record_comp(const uint32_t var, const uint32_t sup_comp_long_
355530
} else continue;
356531
} else {
357532
if (archetype.clause_unvisited_in_sup_comp(d.id)) {
358-
if (is_true(d.blk_lit)) {
533+
if (is_true(d.blk_lit) ||
534+
(d.example_blocking != NOT_A_LIT && is_true(d.example_blocking))) {
359535
archetype.clear_cl(d.id);
360536
sat = true;
361537
goto end_sat;

src/comp_analyzer.hpp

Lines changed: 5 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,10 @@ 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<uint32_t>> lit_to_blocked_clids;
185+
181186
// the id of the last clause
182187
// note that clause ID is the clause number,
183188
// different from the offset of the clause in the literal pool

0 commit comments

Comments
 (0)