From: Sven Verdoolaege Date: Wed, 6 Nov 2013 19:52:58 +0000 (+0100) Subject: gen_fun::add_union: context of result should be the union of the input contexts X-Git-Tag: barvinok-0.37~10 X-Git-Url: https://repo.or.cz/w/barvinok.git/commitdiff_plain/d618acb3e215c840f056d42cc05092a1acfd7ba8 gen_fun::add_union: context of result should be the union of the input contexts The original implementation would keep the context of one of the arguments instead. Note that this commit does not have any user visible effect since the only call to add_union in the source is followed by a replacement of the context. Only users who directly call this undocumented method should be affected. Reported-by: Matt Fredrikson Signed-off-by: Sven Verdoolaege --- diff --git a/barvinok/genfun.h b/barvinok/genfun.h index 2faa3f8..be7ab95 100644 --- a/barvinok/genfun.h +++ b/barvinok/genfun.h @@ -81,6 +81,7 @@ struct gen_fun { clear_terms(); } private: + void extend_context(const gen_fun *gf, barvinok_options *options); void add(const QQ& c, const gen_fun *gf); }; diff --git a/genfun.cc b/genfun.cc index f287677..934cd56 100644 --- a/genfun.cc +++ b/genfun.cc @@ -250,14 +250,22 @@ void gen_fun::add(short_rat *r) term.insert(r); } -void gen_fun::add(const QQ& c, const gen_fun *gf, barvinok_options *options) +/* Extend the context of "this" to include the one of "gf". + */ +void gen_fun::extend_context(const gen_fun *gf, barvinok_options *options) { Polyhedron *U = DomainUnion(context, gf->context, options->MaxRays); Polyhedron *C = DomainConvex(U, options->MaxRays); Domain_Free(U); Domain_Free(context); context = C; +} +/* Add the generating "gf" to "this" on the union of their domains. + */ +void gen_fun::add(const QQ& c, const gen_fun *gf, barvinok_options *options) +{ + extend_context(gf, options); add(c, gf); } @@ -675,11 +683,19 @@ gen_fun *gen_fun::Hadamard_product(const gen_fun *gf, barvinok_options *options) return sum; } +/* Assuming "this" and "gf" are generating functions for sets, + * replace "this" by the generating function for the union of these sets. + * + * In particular, compute + * + * this + gf - gen_fun(intersection of sets) + */ void gen_fun::add_union(gen_fun *gf, barvinok_options *options) { QQ one(1, 1), mone(-1, 1); gen_fun *hp = Hadamard_product(gf, options); + extend_context(gf, options); add(one, gf); add(mone, hp); delete hp;