1717
1818 ******************************************************************************/
1919
20+ #include < set>
21+
2022#include " sbg/set.hpp"
2123
2224namespace SBG {
@@ -234,8 +236,8 @@ SetDelegPtr UnorderedSet::complementAtom() const
234236 for (const Interval &i : mdi) dense_mdi.emplaceBack (Interval (i.begin (), 1 , i.end ()));
235237 SetPiece during_mdi = dense_mdi;
236238
237- Interval univ (0 , 1 , Inf);
238- SetPiece all (mdi.arity (), univ );
239+ Interval univ_one_dim (0 , 1 , Inf);
240+ SetPiece univ (mdi.arity (), univ_one_dim );
239241
240242 unsigned int dim = 0 ;
241243 for (const Interval &i : mdi) {
@@ -245,9 +247,9 @@ SetDelegPtr UnorderedSet::complementAtom() const
245247 if (i.begin () != 0 ) {
246248 Interval i_res (0 , 1 , i.begin () - 1 );
247249 if (!i_res.isEmpty ()) {
248- all [dim] = i_res;
249- c.push_back (all );
250- all [dim] = univ ;
250+ univ [dim] = i_res;
251+ c.push_back (univ );
252+ univ [dim] = univ_one_dim ;
251253 }
252254 }
253255
@@ -268,12 +270,12 @@ SetDelegPtr UnorderedSet::complementAtom() const
268270 if (i.end () < Inf) {
269271 Interval i_res (i.end () + 1 , 1 , Inf);
270272 if (!i_res.isEmpty ()) {
271- all [dim] = i_res;
272- c.push_back (all );
273- all [dim] = univ ;
273+ univ [dim] = i_res;
274+ c.push_back (univ );
275+ univ [dim] = univ_one_dim ;
274276 }
275277 }
276- all [dim] = dense_mdi[dim];
278+ univ [dim] = dense_mdi[dim];
277279 during_mdi[dim] = i;
278280
279281 // Insert results of current dim
@@ -289,15 +291,17 @@ SetDelegPtr UnorderedSet::complement() const
289291{
290292 SetDelegPtr res = std::make_unique<UnorderedSet>(MDIUnordSet ());
291293
292- auto first_it = pieces_.begin ();
293- SetPiece first = *first_it;
294- res = std::move (UnorderedSet (first).complementAtom ());
294+ if (!isEmpty ()) {
295+ auto first_it = pieces_.begin ();
296+ SetPiece first = *first_it;
297+ res = std::move (UnorderedSet (first).complementAtom ());
295298
296- ++first_it;
297- MDIUnordSet second (first_it, pieces_.end ());
298- for (const SetPiece &mdi : second) {
299- SetDelegPtr c = UnorderedSet (mdi).complementAtom ();
300- res = std::move (res->intersection (*c));
299+ ++first_it;
300+ MDIUnordSet second (first_it, pieces_.end ());
301+ for (const SetPiece &mdi : second) {
302+ SetDelegPtr c = UnorderedSet (mdi).complementAtom ();
303+ res = std::move (res->intersection (*c));
304+ }
301305 }
302306
303307 return res;
@@ -355,27 +359,38 @@ SetDelegPtr UnorderedSet::offset(const MD_NAT &off) const
355359
356360SetDelegPtr UnorderedSet::compact () const
357361{
358- // New idea TODO
359- // MDIUnordSet old_compact = pieces_, compact = old_compact;
360- // SetPiece ith(compact.begin());
361- // do {
362- // for (const SetPiece &mdi : compact) {
363- // auto ith_compact = ith.compact(mdi);
364- // if (ith_compact)
365- // ith = ith_compact.value();
366- // }
367- // MDIUnordSet aux_compact = compact;
368- // for (const SetPiece &mdi : aux_compact) {
369- // if (!ith.intersection(mdi).isEmpty())
370- // compact.erase(mdi);
371- // }
372- // compact.emplace(ith);
373- // } while (old_compact != compact);
374-
375- // std::shared_ptr<UnorderedSet> res = std::make_shared<UnorderedSet>();
376- // res->pieces_ = pieces_.compact();
377-
378- return std::make_unique<UnorderedSet>(pieces_);
362+ MDIUnordSet res;
363+
364+ if (!isEmpty ()) {
365+ std::set<SetPiece> prev (pieces_.begin (), pieces_.end ()), actual = prev;
366+ do {
367+ prev = actual;
368+ actual = std::set<SetPiece>();
369+
370+ std::set<SetPiece>::iterator ith = prev.begin (), last = prev.end ();
371+ std::set<SetPiece> to_erase;
372+ for (; ith != last; ++ith) {
373+ SetPiece ith_compact = *ith;
374+ std::set<SetPiece>::iterator next = ith;
375+ ++next;
376+ for (; next != last; ++next) {
377+ MaybeMDI new_compact = ith_compact.compact (*next);
378+ if (new_compact) {
379+ ith_compact = new_compact.value ();
380+ to_erase.insert (*next);
381+ }
382+ }
383+
384+ if (to_erase.find (ith_compact) == to_erase.end ())
385+ actual.insert (ith_compact);
386+ }
387+ } while (actual != prev);
388+
389+ for (const SetPiece &mdi : actual)
390+ res.push_back (mdi);
391+ }
392+
393+ return std::make_unique<UnorderedSet>(res);
379394}
380395
381396// //////////////////////////////////////////////////////////////////////////////
0 commit comments