From ac843dd586e380d33ea506af182f2e3eed7c546d Mon Sep 17 00:00:00 2001 From: kalashnikovni Date: Thu, 27 Jul 2023 09:00:03 -0300 Subject: [PATCH] Fixed pw_inter complement --- sbg/interval.cpp | 8 +++- sbg/interval.hpp | 6 +-- sbg/pw_inter.cpp | 78 +++++++++++++++++++++------------ sbg/pw_inter.hpp | 1 + test/eval/gt_data/set/SBG.log | 23 +++++++--- test/parser/gt_data/set/SBG.log | 5 ++- test/set.test | 4 +- 7 files changed, 81 insertions(+), 44 deletions(-) diff --git a/sbg/interval.cpp b/sbg/interval.cpp index 880c925..0907a54 100755 --- a/sbg/interval.cpp +++ b/sbg/interval.cpp @@ -24,6 +24,7 @@ namespace SBG { namespace LIB { Interval::Interval() : begin_(1), step_(1), end_(0) {} +Interval::Interval(NAT x) : begin_(x), step_(1), end_(x) {} Interval::Interval(NAT begin, NAT step, NAT end) : begin_(begin), step_(step), end_(end) { if (end >= begin) { @@ -65,7 +66,12 @@ std::ostream &operator<<(std::ostream &out, const Interval &i) // Set functions --------------------------------------------------------------- -unsigned int cardinal(Interval i) { return (i.end() - i.begin()) / i.step() + 1; } +unsigned int cardinal(Interval i) +{ + if (!isEmpty(i)) return (i.end() - i.begin()) / i.step() + 1; + + return 0; +} bool isEmpty(Interval i) { return i.end() < i.begin(); } diff --git a/sbg/interval.hpp b/sbg/interval.hpp index fc6c0db..e6a7fa1 100755 --- a/sbg/interval.hpp +++ b/sbg/interval.hpp @@ -28,12 +28,11 @@ ******************************************************************************/ -#ifndef SBG_NATERVAL_HPP -#define SBG_NATERVAL_HPP +#ifndef SBG_INTERVAL_HPP +#define SBG_INTERVAL_HPP #include #include -#include #include #include @@ -51,6 +50,7 @@ struct Interval { member_class(NAT, end); Interval(); + Interval(NAT x); Interval(NAT begin, NAT step, NAT end); eq_class(Interval); diff --git a/sbg/pw_inter.cpp b/sbg/pw_inter.cpp index cd05d9f..5173991 100755 --- a/sbg/pw_inter.cpp +++ b/sbg/pw_inter.cpp @@ -169,16 +169,22 @@ PWInterval cup(PWInterval pwi1, PWInterval pwi2) // As the complement operation will add intervals to our set, we choose the // one with least quantity of them. PWInterval lt_pieces, gt_pieces; - if (pwi1.pieces().size() > pwi2.pieces().size()) { - lt_pieces = pwi2; - gt_pieces = pwi1; - } + int c_size1 = 0, c_size2 = 0; + BOOST_FOREACH (Interval i1, pwi1.pieces()) + c_size1 += i1.step(); + BOOST_FOREACH (Interval i2, pwi2.pieces()) + c_size2 += i2.step(); - else { + if (c_size1 < c_size2) { lt_pieces = pwi1; gt_pieces = pwi2; } + else { + lt_pieces = pwi2; + gt_pieces = pwi1; + } + PWInterval diff = difference(gt_pieces, lt_pieces); if (isCompact(lt_pieces) && isCompact(gt_pieces)) un = traverse(lt_pieces, diff, &least); @@ -194,41 +200,55 @@ PWInterval cup(PWInterval pwi1, PWInterval pwi2) return PWInterval(un); } -PWInterval complement(PWInterval pwi) +PWInterval complement(Interval i) { InterSet c; - if (isEmpty(pwi)) return PWInterval(SetPiece(0, 1, Util::Inf)); + // Before interval + if (i.begin() != 0) { + SetPiece i_res(0, 1, i.begin() - 1); + if (!isEmpty(i_res)) + c.emplace_hint(c.cend(), i_res); + } - Util::NAT last_end = 0; - BOOST_FOREACH (SetPiece i, pwi.pieces()){ - // Before interval - if (i.begin() != 0) { - SetPiece i_res(last_end, 1, i.begin() - 1); + // "During" interval + if (i.begin() < Util::Inf) { + for (Util::NAT j = 1; j < i.step(); j++) { + SetPiece i_res(i.begin() + j, i.step(), i.end()); if (!isEmpty(i_res)) c.emplace_hint(c.cend(), i_res); - } - - // "During" interval - if (i.begin() < Util::Inf) - for (Util::NAT j = 1; j < i.step(); j++) { - SetPiece i_res(i.begin() + j, i.step(), i.end()); - if (!isEmpty(i_res)) - c.emplace_hint(c.cend(), i_res); - } - - last_end = i.end() + 1; + } } - // After intervals - last_end = maxElem(pwi); - if (last_end < Util::Inf) - c.insert(SetPiece(last_end + 1, 1, Util::Inf)); + // After interval + if (maxElem(i) < Util::Inf) + c.insert(SetPiece(maxElem(i) + 1, 1, Util::Inf)); else - c.insert(SetPiece(Util::Inf, 1, Util::Inf)); + c.insert(SetPiece(Util::Inf)); + + + return c; +} + +PWInterval complement(PWInterval pwi) +{ + PWInterval res; + + if (isEmpty(pwi)) return PWInterval(SetPiece(0, 1, Util::Inf)); + + InterSetIt first_it = pwi.pieces_ref().begin(); + SetPiece first = *first_it; + res = complement(first); + + ++first_it; + InterSet second(first_it, pwi.pieces_ref().end()); + BOOST_FOREACH (Interval i, second) { + PWInterval c = complement(i); + res = intersection(res, c); + } - return PWInterval(c); + return res; } PWInterval difference(PWInterval pwi1, PWInterval pwi2) { return intersection(pwi1, complement(pwi2)); } diff --git a/sbg/pw_inter.hpp b/sbg/pw_inter.hpp index 2292f0c..e5bf4ab 100755 --- a/sbg/pw_inter.hpp +++ b/sbg/pw_inter.hpp @@ -84,6 +84,7 @@ Util::NAT minElem(PWInterval pwi); Util::NAT maxElem(PWInterval pwi); PWInterval intersection(PWInterval i1, PWInterval i2); PWInterval cup(PWInterval i1, PWInterval i2); +PWInterval complement(Interval i); PWInterval complement(PWInterval i); PWInterval difference(PWInterval i1, PWInterval i2); diff --git a/test/eval/gt_data/set/SBG.log b/test/eval/gt_data/set/SBG.log index 40469c0..0a26c51 100644 --- a/test/eval/gt_data/set/SBG.log +++ b/test/eval/gt_data/set/SBG.log @@ -55,13 +55,16 @@ maxElem({[500:3:1000], [1:1:100]}) --> {[1:100], [200:400]} {[1:3:100], [2:3:100]}/\{[0:1:2]} - --> {[1:3:1], [2:3:2]} + --> {[1:1], [2:2]} {[1:10:100], [2:10:100], [3:10:100], [4:10:100], [5:10:100], [6:10:100], [7:10:100], [8:10:100]}/\{[3:1:5], [7:1:8]} - --> {[3:10:3], [4:10:4], [5:10:5], [7:10:7], [8:10:8]} + --> {[3:3], [4:4], [5:5], [7:7], [8:8]} {[1:3:100], [2:3:100]}/\{[0:1:2], [4:6:94], [5:6:95], [6:6:96], [7:6:97], [8:6:98], [100:1:10000]} - --> {[1:3:1], [2:3:2], [4:6:94], [5:6:95], [7:6:97], [8:6:98], [100:3:100]} + --> {[1:1], [2:2], [4:6:94], [5:6:95], [7:6:97], [8:6:98], [100:100]} + +{[3:6:100]}' + --> {[0:2], [4:6:94], [5:6:95], [6:6:96], [7:6:97], [8:6:98], [100:Inf]} {[1:1:100], [101:2:300]}' --> {[0:0], [102:2:298], [300:Inf]} @@ -69,14 +72,20 @@ maxElem({[500:3:1000], [1:1:100]}) {[1:1:100], [101:3:300]}' --> {[0:0], [102:3:297], [103:3:298], [300:Inf]} -{[3:6:100]}' - --> {[0:2], [4:6:94], [5:6:95], [6:6:96], [7:6:97], [8:6:98], [100:Inf]} +{[3:10:100], [4:10:100], [5:10:100], [6:10:100], [7:10:100], [8:10:100]}' + --> {[0:2], [9:10:89], [10:10:90], [11:10:91], [12:10:92], [99:Inf]} + +{[3:10:100], [4:10:100], [5:10:100], [6:10:100], [7:10:100], [8:10:100], [10:2:12]}' + --> {[0:2], [9:9], [11:11], [19:10:89], [20:10:90], [21:10:91], [22:10:92], [99:Inf]} + +{[3:10:100], [4:10:100], [7:2:11], [28:10:100], [39:10:100]}' + --> {[0:2], [5:5], [6:6], [8:8], [10:10], [12:10:22], [15:10:25], [16:10:26], [17:10:27], [18:18], [19:19], [20:20], [21:21], [29:29], [30:30], [31:31], [32:32], [35:35], [36:36], [37:37], [40:10:90], [41:10:91], [42:10:92], [45:10:85], [46:10:86], [47:10:87], [95:95], [96:96], [97:97], [100:Inf]} {[50:2:150], [300:1:500]}\{[1:1:100], [101:2:300]} --> {[102:2:150], [300:500]} {[1:3:100], [2:3:100]}\{[3:6:100]} - --> {[1:3:1], [2:3:2], [4:6:94], [5:6:95], [7:6:97], [8:6:98], [100:3:100]} + --> {[1:1], [2:2], [4:6:94], [5:6:95], [7:6:97], [8:6:98], [100:100]} {}\/{[1:1:100]} --> {[1:100]} @@ -94,7 +103,7 @@ maxElem({[500:3:1000], [1:1:100]}) --> {[1:100], [50:2:150], [101:2:299], [300:500]} {[1:1:100], [150:1:250], [450:1:600]}\/{[200:1:300], [425:1:430], [550:1:1000]} - --> {[1:100], [150:250], [251:300], [425:430], [450:600], [601:1000]} + --> {[1:100], [150:199], [200:300], [425:430], [450:549], [550:1000]} {}=={} --> 1 diff --git a/test/parser/gt_data/set/SBG.log b/test/parser/gt_data/set/SBG.log index fb83466..92ba08a 100644 --- a/test/parser/gt_data/set/SBG.log +++ b/test/parser/gt_data/set/SBG.log @@ -21,9 +21,12 @@ maxElem({[500:3:1000], [1:1:100]}) {[1:3:100], [2:3:100]}/\{[0:1:2]} {[1:10:100], [2:10:100], [3:10:100], [4:10:100], [5:10:100], [6:10:100], [7:10:100], [8:10:100]}/\{[3:1:5], [7:1:8]} {[1:3:100], [2:3:100]}/\{[0:1:2], [4:6:94], [5:6:95], [6:6:96], [7:6:97], [8:6:98], [100:1:10000]} +{[3:6:100]}' {[1:1:100], [101:2:300]}' {[1:1:100], [101:3:300]}' -{[3:6:100]}' +{[3:10:100], [4:10:100], [5:10:100], [6:10:100], [7:10:100], [8:10:100]}' +{[3:10:100], [4:10:100], [5:10:100], [6:10:100], [7:10:100], [8:10:100], [10:2:12]}' +{[3:10:100], [4:10:100], [7:2:11], [28:10:100], [39:10:100]}' {[50:2:150], [300:1:500]}\{[1:1:100], [101:2:300]} {[1:3:100], [2:3:100]}\{[3:6:100]} {}\/{[1:1:100]} diff --git a/test/set.test b/test/set.test index f46701d..3be276f 100644 --- a/test/set.test +++ b/test/set.test @@ -28,14 +28,12 @@ maxElem({[500:3:1000], [1:1:100]}) /\ {[3:1:5], [7:1:8]}) ({[1:3:100], [2:3:100]} /\ {[0:1:2], [4:6:94], [5:6:95], [6:6:96], [7:6:97], [8:6:98], [100:1:10000]}) +-{[3:6:100]} -{[1:1:100], [101:2:300]} -{[1:1:100], [101:3:300]} --{[3:6:100]} -{[3:10:100], [4:10:100], [5:10:100], [6:10:100], [7:10:100], [8:10:100]} -{[3:10:100], [4:10:100], [5:10:100], [6:10:100], [7:10:100], [8:10:100], [10:2:12]} -{[3:10:100], [4:10:100], [7:2:11], [28:10:100], [39:10:100]} -{[0:2], [4:10:100], ..., [12:10:100]} -{[0:3], [5:10:100], ..., [13:10:100]} ({[50:2:150], [300:1:500]} \ {[1:1:100], [101:2:300]}) ({[1:3:100], [2:3:100]} \ {[3:6:100]})