[PPL-devel] [GIT] ppl/ppl(bounded_arithmetic): Started the implementation of Polyhedron ::wrap_assign().
Roberto Bagnara
bagnara at cs.unipr.it
Sun Apr 26 23:34:25 CEST 2009
Module: ppl/ppl
Branch: bounded_arithmetic
Commit: df4d4fcfb09051070719d9348382a7e94a8dbf39
URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=df4d4fcfb09051070719d9348382a7e94a8dbf39
Author: Roberto Bagnara <bagnara at cs.unipr.it>
Date: Sun Apr 26 23:34:10 2009 +0200
Started the implementation of Polyhedron::wrap_assign().
---
src/Polyhedron_public.cc | 116 +++++++++++++++++++++++++++++++++++++++++----
tests/Polyhedron/wrap1.cc | 16 ++++++-
2 files changed, 121 insertions(+), 11 deletions(-)
diff --git a/src/Polyhedron_public.cc b/src/Polyhedron_public.cc
index ea0b69e..bd21fa4 100644
--- a/src/Polyhedron_public.cc
+++ b/src/Polyhedron_public.cc
@@ -3460,16 +3460,6 @@ PPL::Polyhedron::time_elapse_assign(const Polyhedron& y) {
}
void
-PPL::Polyhedron::wrap_assign(const Variables_Set& vars,
- Bounded_Integer_Type_Width w,
- Bounded_Integer_Type_Signedness s,
- Bounded_Integer_Type_Overflow o,
- bool wrap_individually,
- unsigned k_threshold) {
- // FIXME: to be written.
-}
-
-void
PPL::Polyhedron::topological_closure_assign() {
// Necessarily closed polyhedra are trivially closed.
if (is_necessarily_closed())
@@ -3685,3 +3675,109 @@ PPL::IO_Operators::operator<<(std::ostream& s, const Polyhedron& ph) {
s << ph.minimized_constraints();
return s;
}
+
+void
+PPL::Polyhedron::wrap_assign(const Variables_Set& vars,
+ Bounded_Integer_Type_Width w,
+ Bounded_Integer_Type_Signedness s,
+ Bounded_Integer_Type_Overflow o,
+ bool wrap_individually,
+ unsigned k_threshold) {
+ // Wrapping no variable is a no-op.
+ if (vars.empty())
+ return;
+
+ // Dimension-compatibility check.
+ const dimension_type min_space_dim = vars.space_dimension();
+ if (space_dim < min_space_dim)
+ throw_dimension_incompatible("wrap_assign(vs, ...)", min_space_dim);
+
+ // Wrapping an empty polyhedron is a no-op.
+ if (is_empty())
+ return;
+
+ // Bound low and bound high assignment.
+ PPL_DIRTY_TEMP_COEFFICIENT(min_value);
+ PPL_DIRTY_TEMP_COEFFICIENT(max_value);
+
+ if (s == UNSIGNED) {
+ min_value = 0;
+ mul_2exp_assign(max_value, Coefficient_one(), w);
+ --max_value;
+ }
+ else {
+ assert(s == SIGNED_2_COMPLEMENT);
+ mul_2exp_assign(max_value, Coefficient_one(), w-1);
+ neg_assign(min_value, max_value);
+ --max_value;
+ }
+
+ //std::cout << "min_value = " << min_value << std::endl;
+ //std::cout << "max_value = " << max_value << std::endl;
+
+ if (wrap_individually) {
+ // We use this to delay conversions when this does not negatively
+ // affect precision.
+ Constraint_System full_range_bounds;
+
+ PPL_DIRTY_TEMP_COEFFICIENT(ln);
+ PPL_DIRTY_TEMP_COEFFICIENT(ld);
+ PPL_DIRTY_TEMP_COEFFICIENT(un);
+ PPL_DIRTY_TEMP_COEFFICIENT(ud);
+
+ //using namespace IO_Operators;
+
+ for (Variables_Set::const_iterator i = vars.begin(),
+ vars_end = vars.end(); i != vars.end(); ++i) {
+
+ const Variable x = Variable(*i);
+ //std::cout << "Wrapping " << x << std::endl;
+
+ bool extremum;
+
+ if (!minimize(x, ln, ld, extremum)) {
+ set_full_range:
+ unconstrain(x);
+ full_range_bounds.insert(min_value <= x);
+ full_range_bounds.insert(x <= max_value);
+ continue;
+ }
+
+ if (!maximize(x, un, ud, extremum))
+ goto set_full_range;
+
+ //std::cout << "min = " << ln << "/" << ld << std::endl;
+ //std::cout << "max = " << un << "/" << ud << std::endl;
+
+ div_assign_r(ln, ln, ld, ROUND_DOWN);
+ div_assign_r(un, un, ud, ROUND_DOWN);
+ ln -= min_value;
+ un -= min_value;
+ div_2exp_assign_r(ln, ln, w, ROUND_DOWN);
+ div_2exp_assign_r(un, un, w, ROUND_DOWN);
+ if (un - ln > k_threshold)
+ goto set_full_range;
+
+ //std::cout << "ln = " << ln << std::endl;
+ //std::cout << "un = " << un << std::endl;
+
+ Polyhedron hull(topology(), space_dimension(), EMPTY);
+ for ( ; ln <= un; ++ln) {
+ Polyhedron p(*this);
+ //std::cout << "p: " << p << std::endl;
+ mul_2exp_assign(ld, ln, w);
+ //std::cout << "ld = " << ld << std::endl;
+ p.affine_image(x, x - ld, 1);
+ //std::cout << "affine_image: " << p << std::endl;
+ p.add_constraint(min_value <= x);
+ p.add_constraint(x <= max_value);
+ hull.poly_hull_assign(p);
+ //std::cout << "hull: " << hull << std::endl;
+ }
+ swap(hull);
+ }
+ add_constraints(full_range_bounds);
+ }
+ else
+ assert(false);
+}
diff --git a/tests/Polyhedron/wrap1.cc b/tests/Polyhedron/wrap1.cc
index dfcb77e..97298f3 100644
--- a/tests/Polyhedron/wrap1.cc
+++ b/tests/Polyhedron/wrap1.cc
@@ -26,7 +26,21 @@ namespace {
bool
test01() {
- // FIXME: to be written.
+ Variable x(0);
+ Variable y(1);
+ C_Polyhedron ph(2, UNIVERSE);
+ ph.add_constraint(x + 1024 == 8*y);
+ ph.add_constraint(-64 <= x);
+ ph.add_constraint(x <= 448);
+
+ print_constraints(ph, "*** ph ***");
+
+ Variables_Set vars(x, y);
+
+ ph.wrap_assign(vars, BITS_8, UNSIGNED, OVERFLOW_WRAPS, true, 10);
+
+ print_constraints(ph.minimized_constraints(), "*** ph.wrap_assign(...) ***");
+
bool ok = true;
return ok;
More information about the PPL-devel
mailing list