[PPL-devel] [GIT] ppl/ppl(floating_point): Wrote a first implementation of refine_with_linear_form_inequality.

Fabio Bossi bossi at cs.unipr.it
Mon Sep 21 14:16:59 CEST 2009


Module: ppl/ppl
Branch: floating_point
Commit: 4f125f4d90aa912d18bcaf8c110a7ff05616ecd2
URL:    http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=4f125f4d90aa912d18bcaf8c110a7ff05616ecd2

Author: Fabio Bossi <bossi at cs.unipr.it>
Date:   Mon Sep 21 14:19:43 2009 +0200

Wrote a first implementation of refine_with_linear_form_inequality.

---

 src/Polyhedron.defs.hh      |    6 ++++
 src/Polyhedron.templates.hh |   54 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/src/Polyhedron.defs.hh b/src/Polyhedron.defs.hh
index d904386..0ef020c 100644
--- a/src/Polyhedron.defs.hh
+++ b/src/Polyhedron.defs.hh
@@ -979,6 +979,12 @@ public:
   */
   void refine_with_congruences(const Congruence_System& cgs);
 
+  template <typename FP_Format, typename Interval_Info>
+  void refine_with_linear_form_inequality(
+  const Linear_Form< Interval<FP_Format, Interval_Info> >& left,
+  const Linear_Form< Interval<FP_Format, Interval_Info> >& right,
+  const std::map< dimension_type, Interval<FP_Format, Interval_Info> >& store);
+
   /*! \brief
     Computes the \ref Cylindrification "cylindrification" of \p *this with
     respect to space dimension \p var, assigning the result to \p *this.
diff --git a/src/Polyhedron.templates.hh b/src/Polyhedron.templates.hh
index 9f4f333..a8e2a07 100644
--- a/src/Polyhedron.templates.hh
+++ b/src/Polyhedron.templates.hh
@@ -298,6 +298,53 @@ Polyhedron::map_space_dimensions(const Partial_Function& pfunc) {
 
 template <typename FP_Format, typename Interval_Info>
 void
+Polyhedron::refine_with_linear_form_inequality(
+  const Linear_Form< Interval<FP_Format, Interval_Info> >& left,
+  const Linear_Form< Interval<FP_Format, Interval_Info> >& right,
+  const std::map< dimension_type, Interval<FP_Format, Interval_Info> >& store) {
+
+  // Check that FP_Format is indeed a floating point type.
+  PPL_COMPILE_TIME_CHECK(!std::numeric_limits<FP_Format>::is_exact,
+                         "Polyhedron::affine_image:"
+                         " FP_Format not a floating point type.");
+
+  // Dimension compatibility checks.
+  // The dimensions of left and right should not be greater than the
+  // dimension of *this.
+  const dimension_type left_space_dim = left.space_dimension();
+  if (space_dim < left_space_dim)
+    throw_dimension_incompatible(
+          "refine_with_linear_form_inequality(l1, l2, s)", "l1", left);
+
+  const dimension_type right_space_dim = right.space_dimension();
+  if (space_dim < right_space_dim)
+    throw_dimension_incompatible(
+          "refine_with_linear_form_inequality(l1, l2, s)", "l2", right);
+
+  // We assume that the analyzer will not refine an unreachable test.
+  PPL_ASSERT(!marked_empty());
+
+  typedef Interval<FP_Format, Interval_Info> FP_Interval_Type;
+  typedef Linear_Form<FP_Interval_Type> FP_Linear_Form;
+
+  // Overapproximate left - right.
+  FP_Linear_Form left_minus_right(left);
+  left_minus_right -= right;
+  dimension_type lf_space_dim = left_minus_right.space_dimension();
+  FP_Linear_Form lf_approx;
+  overapproximate_linear_form(left_minus_right, lf_space_dim, store, lf_approx);
+
+  // Normalize left - right.
+  Linear_Expression lf_approx_le;
+  convert_to_integer_expression(lf_approx, lf_space_dim, lf_approx_le);
+
+  // Finally, do the refinement.
+  refine_with_constraint(lf_approx_le <= 0);
+
+}
+
+template <typename FP_Format, typename Interval_Info>
+void
 Polyhedron::affine_image(const Variable& var,
 const Linear_Form<Interval <FP_Format, Interval_Info> >& lf,
 const std::map< dimension_type, Interval<FP_Format, Interval_Info> >& store) {
@@ -318,7 +365,7 @@ const std::map< dimension_type, Interval<FP_Format, Interval_Info> >& store) {
   if (space_dim < var_id + 1)
     throw_dimension_incompatible("affine_image(v, l, s)", "v", var);
 
-  // We suppose that the analyzer will not filter an unreachable test.
+  // We assume that the analyzer will not perform an unreachable assignment.
   PPL_ASSERT(!marked_empty());
 
   typedef Interval<FP_Format, Interval_Info> FP_Interval_Type;
@@ -363,6 +410,7 @@ Polyhedron::overapproximate_linear_form(
   typedef std::map<dimension_type, FP_Interval_Type> Interval_Abstract_Store;
 
   result = FP_Linear_Form(lf.inhomogeneous_term());
+  // FIXME: this may not be policy-neutral.
   const FP_Interval_Type aux_divisor1(static_cast<FP_Format>(0.5));
   FP_Interval_Type aux_divisor2(aux_divisor1);
   aux_divisor2.lower() = static_cast<FP_Format>(-0.5);
@@ -398,7 +446,7 @@ Polyhedron::convert_to_integer_expression(
   result = Linear_Expression();
 
   typedef Interval<FP_Format, Interval_Info> FP_Interval_Type;
-  typedef typename FP_Interval_Type::coefficient_type FP_Coeff_Type;
+  typedef typename FP_Interval_Type::boundary_type FP_Coeff_Type;
   std::vector<Coefficient> numerators(lf_dimension+1);
   std::vector<Coefficient> denominators(lf_dimension+1);
 
@@ -408,7 +456,7 @@ Polyhedron::convert_to_integer_expression(
   lcm = 1;
   const FP_Interval_Type& b = lf.inhomogeneous_term();
   // FIXME: are these checks numerator[i] != 0 really necessary?
-  numer_denom(b.upper(), numerators[lf_dimension],
+  numer_denom(b.lower(), numerators[lf_dimension],
                          denominators[lf_dimension]);
   if (numerators[lf_dimension] != 0)
       lcm_assign(lcm, lcm, denominators[lf_dimension]);




More information about the PPL-devel mailing list