[util] Minimize the string for infinite sets

Instead of printing every representable member of an infinite set (ie,
up to element 63 in a set that can hold 64 elements), only those
elements up to one after the last non-member are listed. For example,

    {...} - {2 3} -> {0 1 4 ...}

This makes reading (and testing!) infinite sets much easier.
This commit is contained in:
Bill Currie 2021-08-10 12:12:14 +09:00
parent a6a273bb07
commit 37a5b475c0
3 changed files with 37 additions and 70 deletions

View file

@ -392,6 +392,7 @@ struct dstring_s;
will overwrite the results of preceeding calls.
*/
const char *set_as_string (const set_t *set);
/** Return a human-readable string representing the set.
Empty sets will be represented by the string "{}". Sets of everything
@ -406,7 +407,9 @@ const char *set_as_string (const set_t *set);
is appeneded to the string. This makes it more useful when
constructing strings in a threaded environment.
*/
const char *set_as_string_r (struct dstring_s *str, const set_t *set);
const char *set_to_dstring (struct dstring_s *str, const set_t *set);
const char *set_to_dstring_r (set_pool_t *set_pool, struct dstring_s *str,
const set_t *set);
///@}
#endif//__QF_set_h

View file

@ -626,9 +626,10 @@ set_next (set_iter_t *set_iter)
}
const char *
set_as_string_r (dstring_t *str, const set_t *set)
set_to_dstring_r (set_pool_t *set_pool, dstring_t *str, const set_t *set)
{
unsigned i;
set_iter_t *iter;
int first = 1;
if (set_is_empty (set)) {
dstring_appendstr (str, "{}");
@ -639,21 +640,36 @@ set_as_string_r (dstring_t *str, const set_t *set)
return str->str;
}
dstring_appendstr (str, "{");
for (i = 0; i < set->size; i++) {
if (set_is_member (set, i)) {
if (str->str[1])
dasprintf (str, " %d", i);
else
dasprintf (str, "%d", i);
}
}
if (set->inverted) {
dasprintf (str, "%s%d ...", str->str[1] ? " " : "", i);
unsigned start = 0;
for (iter = set_first_r (set_pool, set); iter;
iter = set_next_r (set_pool, iter)) {
unsigned end = iter->element;
while (start < end) {
dasprintf (str, "%s%d", first ? "" : " ", start++);
first = 0;
}
start = end + 1;
}
dasprintf (str, "%s%d ...", first ? "" : " ", start);
} else {
for (iter = set_first_r (set_pool, set); iter;
iter = set_next_r (set_pool, iter)) {
dasprintf (str, "%s%d", first ? "" : " ", iter->element);
first = 0;
}
}
dstring_appendstr (str, "}");
return str->str;
}
const char *
set_to_dstring (dstring_t *str, const set_t *set)
{
return set_to_dstring_r (&static_set_pool, str, set);
}
const char *
set_as_string (const set_t *set)
{
@ -663,5 +679,5 @@ set_as_string (const set_t *set)
str = dstring_new ();
}
dstring_clearstr (str);
return set_as_string_r (str, set);
return set_to_dstring_r (&static_set_pool, str, set);
}

View file

@ -242,39 +242,14 @@ struct {
{make_not_5, 0, 0, check_count, 1, 0},
{make_0_to_SIZEm1, 0, 0, check_size, SIZE, 0},
{make_0_1, 0, 0, 0, 0, "{0 1}"},
{make_not_1_2, 0, 0, check_count, 2,
"{0 3 4 5 6 7 8 9 10 11 12 13 14 15"
" 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31"
" 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47"
" 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 ...}"
},
{make_0_1, make_not_1_2, set_union, check_count, 1,
"{0 1 3 4 5 6 7 8 9 10 11 12 13 14 15"
" 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31"
" 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47"
" 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 ...}"
},
{make_not_1_2, 0, 0, check_count, 2, "{0 3 ...}"},//68
{make_0_1, make_not_1_2, set_union, check_count, 1, "{0 1 3 ...}"},
{make_0_1, make_not_1_2, set_intersection, check_count, 1, "{0}"},
{make_0_1, make_not_1_2, set_difference, check_count, 1, "{1}"},
{make_0_1, make_not_1_2, set_reverse_difference, check_count, 3,
"{3 4 5 6 7 8 9 10 11 12 13 14 15"
" 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31"
" 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47"
" 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 ...}"
},
{make_not_1_2, make_0_1, set_union, check_count, 1,
"{0 1 3 4 5 6 7 8 9 10 11 12 13 14 15"
" 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31"
" 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47"
" 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 ...}"
},
{make_0_1, make_not_1_2, set_reverse_difference, check_count, 3, "{3 ...}"},
{make_not_1_2, make_0_1, set_union, check_count, 1, "{0 1 3 ...}"},
{make_not_1_2, make_0_1, set_intersection, check_count, 1, "{0}"},
{make_not_1_2, make_0_1, set_difference, check_count, 3,
"{3 4 5 6 7 8 9 10 11 12 13 14 15"
" 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31"
" 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47"
" 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 ...}"
},
{make_not_1_2, make_0_1, set_difference, check_count, 3, "{3 ...}"},
{make_not_1_2, make_0_1, set_reverse_difference, check_count, 1, "{1}"},
};
#define num_tests (sizeof (tests) / sizeof (tests[0]))
@ -303,33 +278,6 @@ main (int argc, const char **argv)
dstring_appendstr (str, "}");
tests[6].str_expect = dstring_freeze (str);
str = dstring_new ();
for (i = 0; i < SIZE; i++) {
if (i == 1 || i == 2)
continue;
dasprintf (str, "%c%zd", i > 0 ? ' ' : '{', i);
}
dasprintf (str, " %zd ...}", i);
tests[68].str_expect = dstring_freeze (str);
str = dstring_new ();
for (i = 0; i < SIZE; i++) {
if (i == 2)
continue;
dasprintf (str, "%c%zd", i > 0 ? ' ' : '{', i);
}
dasprintf (str, " %zd ...}", i);
tests[69].str_expect = dstring_freeze (str);
tests[73].str_expect = tests[69].str_expect;
str = dstring_new ();
for (i = 3; i < SIZE; i++) {
dasprintf (str, "%c%zd", i > 3 ? ' ' : '{', i);
}
dasprintf (str, " %zd ...}", i);
tests[72].str_expect = dstring_freeze (str);
tests[75].str_expect = tests[72].str_expect;
for (i = 0; i < num_tests; i++) {
set_t *s1, *s2 = 0;
const char *set_str;