gen_fun::add_union: context of result should be the union of the input contexts
authorSven Verdoolaege <skimo@kotnet.org>
Wed, 6 Nov 2013 19:52:58 +0000 (6 20:52 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Mon, 10 Mar 2014 08:55:15 +0000 (10 09:55 +0100)
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 <mfredrik@cs.wisc.edu>
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
barvinok/genfun.h
genfun.cc

index 2faa3f8..be7ab95 100644 (file)
@@ -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);
 };
 
index f287677..934cd56 100644 (file)
--- 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;