@@ -30,6 +30,7 @@ THE SOFTWARE.
3030#include < cstdint>
3131#include < cstdint>
3232#include < memory>
33+ #include < ratio>
3334
3435using 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
45200void 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;
0 commit comments