Parma_Polyhedra_Library::Implementation::Termination Namespace Reference

Functions

void assign_all_inequalities_approximation (const Constraint_System &cs_in, Constraint_System &cs_out)
template<typename PSET >
void assign_all_inequalities_approximation (const PSET &pset, Constraint_System &cs)
template<>
void assign_all_inequalities_approximation (const C_Polyhedron &ph, Constraint_System &cs)
void shift_unprimed_variables (Constraint_System &cs)
template<typename PSET >
void assign_all_inequalities_approximation (const PSET &pset_before, const PSET &pset_after, Constraint_System &cs)
bool termination_test_MS (const Constraint_System &cs)
bool one_affine_ranking_function_MS (const Constraint_System &cs, Generator &mu)
void all_affine_ranking_functions_MS (const Constraint_System &cs, C_Polyhedron &mu_space)
void all_affine_quasi_ranking_functions_MS (const Constraint_System &cs, C_Polyhedron &decreasing_mu_space, C_Polyhedron &bounded_mu_space)
bool termination_test_PR (const Constraint_System &cs_before, const Constraint_System &cs_after)
bool one_affine_ranking_function_PR (const Constraint_System &cs_before, const Constraint_System &cs_after, Generator &mu)
void all_affine_ranking_functions_PR (const Constraint_System &cs_before, const Constraint_System &cs_after, NNC_Polyhedron &mu_space)
bool termination_test_PR_original (const Constraint_System &cs)
bool one_affine_ranking_function_PR_original (const Constraint_System &cs, Generator &mu)
void all_affine_ranking_functions_PR_original (const Constraint_System &cs, NNC_Polyhedron &mu_space)
void fill_constraint_systems_MS (const Constraint_System &cs, Constraint_System &cs_out1, Constraint_System &cs_out2)
 Fill the constraint system(s) for the application of the Mesnard and Serebrenik improved termination tests.
void fill_constraint_system_PR (const Constraint_System &cs_before, const Constraint_System &cs_after, Constraint_System &cs_out, Linear_Expression &le_out)
 Fill the constraint system(s) for the application of the Podelski and Rybalchenko improved termination tests.
void fill_constraint_system_PR_original (const Constraint_System &cs, Constraint_System &cs_out, Linear_Expression &le_out)

Function Documentation

void Parma_Polyhedra_Library::Implementation::Termination::all_affine_quasi_ranking_functions_MS ( const Constraint_System &  cs,
C_Polyhedron &  decreasing_mu_space,
C_Polyhedron &  bounded_mu_space 
)

Definition at line 558 of file termination.cc.

00566                                                                       {
00567   Constraint_System cs_out1;
00568   Constraint_System cs_out2;
00569   fill_constraint_systems_MS(cs, cs_out1, cs_out2);
00570 
00571   C_Polyhedron ph1(cs_out1);
00572   C_Polyhedron ph2(cs_out2);
00573   const dimension_type n = cs.space_dimension() / 2;
00574   ph1.remove_higher_space_dimensions(n);
00575   ph1.add_space_dimensions_and_embed(1);
00576   ph2.remove_higher_space_dimensions(n+1);
00577 
00578 #if PRINT_DEBUG_INFO
00579   Variable::output_function_type* p_default_output_function
00580     = Variable::get_output_function();
00581   Variable::set_output_function(output_function_MS);
00582 
00583   output_function_MS_n = n;
00584   output_function_MS_m = std::distance(cs.begin(), cs.end());
00585 
00586   std::cout << "*** ph1 projected ***" << std::endl;
00587   output_function_MS_which = 4;
00588   using namespace IO_Operators;
00589   std::cout << ph1.minimized_constraints() << std::endl;
00590 
00591   std::cout << "*** ph2 projected ***" << std::endl;
00592   std::cout << ph2.minimized_constraints() << std::endl;
00593 

void Parma_Polyhedra_Library::Implementation::Termination::all_affine_ranking_functions_MS ( const Constraint_System &  cs,
C_Polyhedron &  mu_space 
)

Definition at line 514 of file termination.cc.

00521                                                         {
00522   Constraint_System cs_out1;
00523   Constraint_System cs_out2;
00524   fill_constraint_systems_MS(cs, cs_out1, cs_out2);
00525 
00526   C_Polyhedron ph1(cs_out1);
00527   C_Polyhedron ph2(cs_out2);
00528   const dimension_type n = cs.space_dimension() / 2;
00529   ph1.remove_higher_space_dimensions(n);
00530   ph1.add_space_dimensions_and_embed(1);
00531   ph2.remove_higher_space_dimensions(n+1);
00532 
00533 #if PRINT_DEBUG_INFO
00534   Variable::output_function_type* p_default_output_function
00535     = Variable::get_output_function();
00536   Variable::set_output_function(output_function_MS);
00537 
00538   output_function_MS_n = n;
00539   output_function_MS_m = std::distance(cs.begin(), cs.end());
00540 
00541   std::cout << "*** ph1 projected ***" << std::endl;
00542   output_function_MS_which = 4;
00543   using namespace IO_Operators;
00544   std::cout << ph1.minimized_constraints() << std::endl;
00545 
00546   std::cout << "*** ph2 projected ***" << std::endl;
00547   std::cout << ph2.minimized_constraints() << std::endl;
00548 #endif
00549 
00550   ph1.intersection_assign(ph2);
00551 
00552 #if PRINT_DEBUG_INFO
00553   std::cout << "*** intersection ***" << std::endl;
00554   using namespace IO_Operators;
00555   std::cout << ph1.minimized_constraints() << std::endl;

void Parma_Polyhedra_Library::Implementation::Termination::all_affine_ranking_functions_PR ( const Constraint_System &  cs_before,
const Constraint_System &  cs_after,
NNC_Polyhedron &  mu_space 
)

Definition at line 757 of file termination.cc.

00765                                                           {
00766   Constraint_System cs_eqs;
00767   Linear_Expression le_ineq;
00768   fill_constraint_system_PR(cs_before, cs_after, cs_eqs, le_ineq);
00769 
00770 #if PRINT_DEBUG_INFO
00771   Variable::output_function_type* p_default_output_function
00772     = Variable::get_output_function();
00773   Variable::set_output_function(output_function_PR);
00774 
00775   output_function_PR_r = distance(cs_before.begin(), cs_before.end());
00776   output_function_PR_s = distance(cs_after.begin(), cs_after.end());
00777 
00778   std::cout << "*** cs_eqs ***" << std::endl;
00779   using namespace IO_Operators;
00780   std::cout << cs_eqs << std::endl;
00781   std::cout << "*** le_ineq ***" << std::endl;
00782   std::cout << le_ineq << std::endl;
00783 #endif
00784 
00785   NNC_Polyhedron ph(cs_eqs);
00786   ph.add_constraint(le_ineq < 0);
00787   // u_3 corresponds to space dimensions 0, ..., s - 1.
00788   const dimension_type s = distance(cs_after.begin(), cs_after.end());
00789   ph.remove_higher_space_dimensions(s);
00790 
00791 #if PRINT_DEBUG_INFO
00792   std::cout << "*** ph ***" << std::endl;
00793   std::cout << ph << std::endl;
00794 
00795   Variable::set_output_function(p_default_output_function);
00796 #endif
00797 
00798   const dimension_type n = cs_before.space_dimension();
00799 
00800   const Generator_System& gs_in = ph.generators();
00801   Generator_System gs_out;
00802   Generator_System::const_iterator gs_in_it = gs_in.begin();
00803   Generator_System::const_iterator gs_in_end = gs_in.end();
00804   if (gs_in_it == gs_in_end)
00805     // The system is unsatisfiable.
00806     mu_space = NNC_Polyhedron(n + 1, EMPTY);
00807   else {
00808     for ( ; gs_in_it != gs_in_end; ++gs_in_it) {
00809       const Generator& g = *gs_in_it;
00810       Linear_Expression le;
00811       // Set le to the multiplication of Linear_Expression(g) by E'_C.
00812       dimension_type row_index = 0;
00813       PPL_DIRTY_TEMP_COEFFICIENT(k);
00814       for (Constraint_System::const_iterator i = cs_after.begin(),
00815              cs_after_end = cs_after.end();
00816            i != cs_after_end;
00817            ++i, ++row_index) {
00818         Variable vi(row_index);
00819         Coefficient_traits::const_reference g_i = g.coefficient(vi);
00820         if (g_i != 0) {
00821           const Constraint& c_i = *i;
00822           for (dimension_type j = n; j-- > 0; ) {
00823             Variable vj(j);
00824             k = g_i * c_i.coefficient(vj);
00825             sub_mul_assign(le, k, vj);
00826           }
00827         }
00828       }
00829 
00830       // Add to gs_out the transformed generator.
00831       switch (g.type()) {
00832       case Generator::LINE:
00833         if (!le.all_homogeneous_terms_are_zero())
00834           gs_out.insert(line(le));
00835         break;
00836       case Generator::RAY:
00837         if (!le.all_homogeneous_terms_are_zero())
00838           gs_out.insert(ray(le));
00839         break;
00840       case Generator::POINT:
00841         gs_out.insert(point(le, g.divisor()));
00842         break;
00843       case Generator::CLOSURE_POINT:
00844         gs_out.insert(closure_point(le, g.divisor()));
00845         break;
00846       }
00847     }

void Parma_Polyhedra_Library::Implementation::Termination::all_affine_ranking_functions_PR_original ( const Constraint_System &  cs,
NNC_Polyhedron &  mu_space 
)

Definition at line 850 of file termination.cc.

Referenced by Parma_Polyhedra_Library::all_affine_ranking_functions_PR().

00857                                                                    {
00858   PPL_ASSERT(cs.space_dimension() % 2 == 0);
00859   const dimension_type n = cs.space_dimension() / 2;
00860   const dimension_type m = distance(cs.begin(), cs.end());
00861 
00862   if (m == 0) {
00863     // If there are no constraints at all, we have non-termination,
00864     // i.e., no affine ranking function at all.
00865     mu_space = NNC_Polyhedron(n + 1, EMPTY);
00866     return;
00867   }
00868 
00869   Constraint_System cs_eqs;
00870   Linear_Expression le_ineq;
00871   fill_constraint_system_PR_original(cs, cs_eqs, le_ineq);
00872 
00873   NNC_Polyhedron ph(cs_eqs);
00874   ph.add_constraint(le_ineq < 0);
00875   // lambda_2 corresponds to space dimensions m, ..., 2*m-1.
00876   Variables_Set lambda1(Variable(0), Variable(m-1));
00877   ph.remove_space_dimensions(lambda1);
00878   //ph.remove_higher_space_dimensions(m);
00879 
00880 #if PRINT_DEBUG_INFO
00881   std::cout << "*** ph ***" << std::endl;
00882   std::cout << ph << std::endl;
00883 
00884   Variable::set_output_function(p_default_output_function);
00885 #endif
00886 
00887   const Generator_System& gs_in = ph.generators();
00888   Generator_System gs_out;
00889   Generator_System::const_iterator gs_in_it = gs_in.begin();
00890   Generator_System::const_iterator gs_in_end = gs_in.end();
00891   if (gs_in_it == gs_in_end)
00892     // The system is unsatisfiable.
00893     mu_space = NNC_Polyhedron(n + 1, EMPTY);
00894   else {
00895     for ( ; gs_in_it != gs_in_end; ++gs_in_it) {
00896       const Generator& g = *gs_in_it;
00897       Linear_Expression le;
00898       // Set le to the multiplication of Linear_Expression(g) by E'_C.
00899       dimension_type row_index = 0;
00900       PPL_DIRTY_TEMP_COEFFICIENT(k);
00901       for (Constraint_System::const_iterator i = cs.begin(),
00902              cs_end = cs.end(); i != cs_end; ++i, ++row_index) {
00903         Variable lambda2_i(row_index);
00904         Coefficient_traits::const_reference g_i = g.coefficient(lambda2_i);
00905         if (g_i != 0) {
00906           const Constraint& c_i = *i;
00907           for (dimension_type j = n; j-- > 0; ) {
00908             Variable vj(j);
00909             Coefficient_traits::const_reference Ap_ij = c_i.coefficient(vj);
00910             k = g_i * Ap_ij;
00911             sub_mul_assign(le, k, vj);
00912           }
00913         }
00914       }
00915 
00916       // Add to gs_out the transformed generator.
00917       switch (g.type()) {
00918       case Generator::LINE:
00919         if (!le.all_homogeneous_terms_are_zero())
00920           gs_out.insert(line(le));
00921         break;
00922       case Generator::RAY:
00923         if (!le.all_homogeneous_terms_are_zero())
00924           gs_out.insert(ray(le));
00925         break;
00926       case Generator::POINT:
00927         gs_out.insert(point(le, g.divisor()));
00928         break;
00929       case Generator::CLOSURE_POINT:
00930         gs_out.insert(closure_point(le, g.divisor()));
00931         break;
00932       }
00933     }

template<typename PSET >
void Parma_Polyhedra_Library::Implementation::Termination::assign_all_inequalities_approximation ( const PSET &  pset_before,
const PSET &  pset_after,
Constraint_System &  cs 
) [inline]

Definition at line 161 of file termination.templates.hh.

References assign_all_inequalities_approximation(), Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Constraint_System::insert(), and shift_unprimed_variables().

00163                                                              {
00164   assign_all_inequalities_approximation(pset_before, cs);
00165   shift_unprimed_variables(cs);
00166   Constraint_System cs_after;
00167   assign_all_inequalities_approximation(pset_after, cs_after);
00168   // FIXME: provide an "append" for constraint systems.
00169   for (Constraint_System::const_iterator i = cs_after.begin(),
00170          cs_after_end = cs_after.end(); i != cs_after_end; ++i)
00171     cs.insert(*i);
00172 }

template<>
void Parma_Polyhedra_Library::Implementation::Termination::assign_all_inequalities_approximation ( const C_Polyhedron &  ph,
Constraint_System &  cs 
) [inline]

Definition at line 58 of file termination.cc.

00065                                                              {
00066   const Constraint_System& ph_cs = ph.minimized_constraints();
00067   if (ph_cs.has_equalities()) {
00068     // Translate equalities into inequalities.
00069     for (Constraint_System::const_iterator i = ph_cs.begin(),
00070            i_end = ph_cs.end(); i != i_end; ++i) {
00071       const Constraint& c = *i;
00072       if (c.is_equality()) {
00073         // Insert the two corresponding opposing inequalities.
00074         cs.insert(Linear_Expression(c) >= 0);
00075         cs.insert(Linear_Expression(c) <= 0);
00076       }
00077       else
00078         // Insert as is.
00079         cs.insert(c);

template<typename PSET >
void Parma_Polyhedra_Library::Implementation::Termination::assign_all_inequalities_approximation ( const PSET &  pset,
Constraint_System &  cs 
) [inline]

Definition at line 146 of file termination.templates.hh.

References assign_all_inequalities_approximation().

00147                                                              {
00148   assign_all_inequalities_approximation(pset.minimized_constraints(), cs);
00149 }

void Parma_Polyhedra_Library::Implementation::Termination::assign_all_inequalities_approximation ( const Constraint_System &  cs_in,
Constraint_System &  cs_out 
)

Definition at line 30 of file termination.cc.

References Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Constraint_System::has_equalities(), Parma_Polyhedra_Library::Constraint_System::has_strict_inequalities(), Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::Constraint::is_equality(), and Parma_Polyhedra_Library::Constraint::is_strict_inequality().

Referenced by Parma_Polyhedra_Library::all_affine_quasi_ranking_functions_MS(), Parma_Polyhedra_Library::all_affine_quasi_ranking_functions_MS_2(), Parma_Polyhedra_Library::all_affine_ranking_functions_MS(), Parma_Polyhedra_Library::all_affine_ranking_functions_MS_2(), Parma_Polyhedra_Library::all_affine_ranking_functions_PR(), Parma_Polyhedra_Library::all_affine_ranking_functions_PR_2(), assign_all_inequalities_approximation(), Parma_Polyhedra_Library::one_affine_ranking_function_MS(), Parma_Polyhedra_Library::one_affine_ranking_function_MS_2(), Parma_Polyhedra_Library::one_affine_ranking_function_PR(), Parma_Polyhedra_Library::one_affine_ranking_function_PR_2(), Parma_Polyhedra_Library::termination_test_MS(), Parma_Polyhedra_Library::termination_test_MS_2(), Parma_Polyhedra_Library::termination_test_PR(), and Parma_Polyhedra_Library::termination_test_PR_2().

00031                          {
00032 
00033 namespace Termination {
00034 
00035 void
00036 assign_all_inequalities_approximation(const Constraint_System& cs_in,
00037                                       Constraint_System& cs_out) {
00038   if (cs_in.has_strict_inequalities() || cs_in.has_equalities()) {
00039     // Here we have some strict inequality and/or equality constraints:
00040     // translate them into non-strict inequality constraints.
00041     for (Constraint_System::const_iterator i = cs_in.begin(),
00042            i_end = cs_in.end(); i != i_end; ++i) {
00043       const Constraint& c = *i;
00044       if (c.is_equality()) {
00045         // Insert the two corresponding opposing inequalities.
00046         cs_out.insert(Linear_Expression(c) >= 0);
00047         cs_out.insert(Linear_Expression(c) <= 0);
00048       }
00049       else if (c.is_strict_inequality())
00050         // Insert the non-strict approximation.
00051         cs_out.insert(Linear_Expression(c) >= 0);
00052       else
00053         // Insert as is.
00054         cs_out.insert(c);

void Parma_Polyhedra_Library::Implementation::Termination::fill_constraint_system_PR ( const Constraint_System &  cs_before,
const Constraint_System &  cs_after,
Constraint_System &  cs_out,
Linear_Expression &  le_out 
)

Fill the constraint system(s) for the application of the Podelski and Rybalchenko improved termination tests.

Parameters:
cs_before The input constraint system describing the state before the execution of the loop body, where variables indices are allocated as follows:

  • $ x_1, \ldots, x_n $ go onto space dimensions $ 0, \ldots, n-1 $.

The system does not contain any equality.

cs_after The input constraint system describing the state after the execution of the loop body, where variables indices are allocated as follows:

  • $ x'_1, \ldots, x'_n $ go onto space dimensions $ 0, \ldots, n-1 $,
  • $ x_1, \ldots, x_n $ go onto space dimensions $ n, \ldots, 2n-1 $.

The system does not contain any equality.

cs_out The output constraint system, where variables indices are allocated as follows:

  • $ u_3 $ goes onto space dimensions $ 0, \ldots, s-1 $;
  • $ u_2 $ goes onto space dimensions $ s, \ldots, s+r-1 $;
  • $ u_1 $ goes onto space dimensions $ s+r, \ldots, s+2r-1 $.

The improved Podelski-Rybalchenko method described in the paper is based on a loop encoding of the form

\[ \begin{pmatrix} A_B & \vect{0} \\ A_C & A'_C \end{pmatrix} \begin{pmatrix} \vect{x} \\ \vect{x}' \end{pmatrix} \leq \begin{pmatrix} \vect{b}_B \\ \vect{b}_C \end{pmatrix}, \]

where $ A_B \in \Qset^{r \times n} $, $ A_C \in \Qset^{s \times n} $, $ A'_C \in \Qset^{s \times n} $, $ \vect{b}_B \in \Qset^r $, $ \vect{b}_C \in \Qset^s $. The corresponding system is:

\[ \begin{aligned} (\vect{v}_1-\vect{v}_2)^\transpose A_B - \vect{v}_3^\transpose A_C &= \vect{0}^\transpose, \\ \vect{v}_2^\transpose A_B + \vect{v}_3^\transpose (A_C+A_C') &= \vect{0}^\transpose, \\ \vect{v}_2 \vect{b}_B + \vect{v}_3 \vect{b}_C &< 0, \end{aligned} \]

where $ \vect{v}_1 \in \Qset_+^r $, $ \vect{v}_2 \in \Qset_+^r $, $ \vect{v}_3 \in \Qset_+^s $. The space of ranking functions is then spanned by $ \vect{v}_3^\transpose A_C' \vect x $.

In contrast, our encoding is of the form

\[ \begin{pmatrix} \vect{0} & E_B \\ E'_C & E_C \end{pmatrix} \begin{pmatrix} \vect{x}' \\ \vect{x} \end{pmatrix} + \begin{pmatrix} \vect{d}_B \\ \vect{d}_C \end{pmatrix} \geq \vect{0}, \]

where $ {E}_B = -{A}_B $, $ {E}_C = -{A}_C $, $ {E}'_C = -{A}'_C $, $ \vect{d}_B = \vect{b}_B $ and $ \vect{d}_C = \vect{b}_C $. The corresponding system is:

\[ \begin{aligned} (\vect{u}_1-\vect{u}_2)^\transpose E_B - \vect{u}_3^\transpose E_C &= \vect{0}^\transpose, \\ \vect{u}_2^\transpose E_B + \vect{u}_3^\transpose (E_C+E_C') &= \vect{0}^\transpose, \\ \vect{u}_2 \vect{d}_B + \vect{u}_3 \vect{d}_C &> 0, \end{aligned} \]

where $ \vect{u}_1 \in \Qset_-^r $, $ \vect{u}_2 \in \Qset_-^r $, $ \vect{u}_3 \in \Qset_-^s $. The space of ranking functions is then spanned by $ \vect{u}_3^\transpose E_C' \vect x $.

Parameters:
le_out The expression to be minimized in the context of cs_out: a value of $ -1 $ or less entails termination.

Definition at line 353 of file termination.cc.

00356                                                             :
00357   a value of \f$ -1 \f$ or less entails termination.
00358 */
00359 void
00360 fill_constraint_system_PR(const Constraint_System& cs_before,
00361                           const Constraint_System& cs_after,
00362                           Constraint_System& cs_out,
00363                           Linear_Expression& le_out) {
00364   PPL_ASSERT(cs_after.space_dimension() % 2 == 0);
00365   PPL_ASSERT(2*cs_before.space_dimension() == cs_after.space_dimension());
00366   const dimension_type n = cs_before.space_dimension();
00367   const dimension_type r = distance(cs_before.begin(), cs_before.end());
00368   const dimension_type s = distance(cs_after.begin(), cs_after.end());
00369   const dimension_type m = r + s;
00370 
00371   // Make sure linear expressions are not reallocated multiple times.
00372   if (m > 0)
00373     le_out = 0 * Variable(m + r - 1);
00374   std::vector<Linear_Expression> les_eq(2*n, le_out);
00375 
00376   dimension_type row_index = 0;
00377   for (Constraint_System::const_iterator i = cs_before.begin(),
00378          cs_before_end = cs_before.end();
00379        i != cs_before_end;
00380        ++i, ++row_index) {
00381     Variable u1_i(m + row_index);
00382     Variable u2_i(s + row_index);
00383     const Constraint& c_i = *i;
00384     for (dimension_type j = n; j-- > 0; ) {
00385       Coefficient_traits::const_reference A_ij_B = c_i.coefficient(Variable(j));
00386       if (A_ij_B != 0) {
00387         // (u1 - u2) A_B, in the context of j-th constraint.
00388         add_mul_assign(les_eq[j], A_ij_B, u1_i);
00389         sub_mul_assign(les_eq[j], A_ij_B, u2_i);
00390         // u2 A_B, in the context of (j+n)-th constraint.
00391         add_mul_assign(les_eq[j + n], A_ij_B, u2_i);
00392       }
00393     }
00394     Coefficient_traits::const_reference b_B = c_i.inhomogeneous_term();
00395     if (b_B != 0)
00396       // u2 b_B, in the context of the strict inequality constraint.
00397       add_mul_assign(le_out, b_B, u2_i);
00398   }
00399 
00400   row_index = 0;
00401   for (Constraint_System::const_iterator i = cs_after.begin(),
00402          cs_after_end = cs_after.end();
00403        i != cs_after_end;
00404        ++i, ++row_index) {
00405     Variable u3_i(row_index);
00406     const Constraint& c_i = *i;
00407     for (dimension_type j = n; j-- > 0; ) {
00408       Coefficient_traits::const_reference
00409         A_ij_C = c_i.coefficient(Variable(j + n));
00410       if (A_ij_C != 0) {
00411         // - u3 A_C, in the context of the j-th constraint.
00412         sub_mul_assign(les_eq[j], A_ij_C, u3_i);
00413         // u3 A_C, in the context of the (j+n)-th constraint.
00414         add_mul_assign(les_eq[j+n], A_ij_C, u3_i);
00415       }
00416       Coefficient_traits::const_reference
00417         Ap_ij_C = c_i.coefficient(Variable(j));
00418       if (Ap_ij_C != 0)
00419         // u3 Ap_C, in the context of the (j+n)-th constraint.
00420         add_mul_assign(les_eq[j+n], Ap_ij_C, u3_i);
00421     }
00422     Coefficient_traits::const_reference b_C = c_i.inhomogeneous_term();
00423     if (b_C != 0)
00424       // u3 b_C, in the context of the strict inequality constraint.
00425       add_mul_assign(le_out, b_C, u3_i);
00426   }
00427 
00428   // Add the nonnegativity constraints for u_1, u_2 and u_3.
00429   for (dimension_type i = s + 2*r; i-- > 0; )
    cs_out.insert(Variable(i) >= 0);

void Parma_Polyhedra_Library::Implementation::Termination::fill_constraint_system_PR_original ( const Constraint_System &  cs,
Constraint_System &  cs_out,
Linear_Expression &  le_out 
)

Definition at line 432 of file termination.cc.

00440                                                               {
00441   PPL_ASSERT(cs.space_dimension() % 2 == 0);
00442   const dimension_type n = cs.space_dimension() / 2;
00443   const dimension_type m = distance(cs.begin(), cs.end());
00444 
00445   // Make sure linear expressions are not reallocated multiple times.
00446   if (m > 0)
00447     le_out = 0 * Variable(2*m - 1);
00448   std::vector<Linear_Expression> les_eq(3*n, le_out);
00449 
00450   dimension_type row_index = 0;
00451   for (Constraint_System::const_iterator i = cs.begin(),
00452          cs_end = cs.end(); i != cs_end; ++i, ++row_index) {
00453     const Constraint& c_i = *i;
00454     const Variable lambda1_i(row_index);
00455     const Variable lambda2_i(m + row_index);
00456     for (dimension_type j = n; j-- > 0; ) {
00457       Coefficient_traits::const_reference Ap_ij = c_i.coefficient(Variable(j));
00458       if (Ap_ij != 0) {
00459         // lambda_1 A'
00460         add_mul_assign(les_eq[j], Ap_ij, lambda1_i);
00461         // lambda_2 A'
00462         add_mul_assign(les_eq[j+n+n], Ap_ij, lambda2_i);
00463       }
00464       Coefficient_traits::const_reference A_ij = c_i.coefficient(Variable(j+n));
00465       if (A_ij != 0) {
00466         // (lambda_1 - lambda_2) A
00467         add_mul_assign(les_eq[j+n], A_ij, lambda1_i);
00468         sub_mul_assign(les_eq[j+n], A_ij, lambda2_i);
00469         // lambda_2 A
00470         add_mul_assign(les_eq[j+n+n], A_ij, lambda2_i);
00471       }
00472     }
00473     Coefficient_traits::const_reference b = c_i.inhomogeneous_term();
00474     if (b != 0)
00475       // lambda2 b
00476       add_mul_assign(le_out, b, lambda2_i);
00477   }
00478 
00479   // Add the non-negativity constraints for lambda_1 and lambda_2.
00480   for (dimension_type i = 2*m; i-- > 0; )
00481     cs_out.insert(Variable(i) >= 0);

void Parma_Polyhedra_Library::Implementation::Termination::fill_constraint_systems_MS ( const Constraint_System &  cs,
Constraint_System &  cs_out1,
Constraint_System &  cs_out2 
)

Fill the constraint system(s) for the application of the Mesnard and Serebrenik improved termination tests.

Parameters:
cs The input constraint system, where variables indices are allocated as follows:

  • $ x'_1, \ldots, x'_n $ go onto space dimensions $ 0, \ldots, n-1 $,
  • $ x_1, \ldots, x_n $ go onto space dimensions $ n, \ldots, 2n-1 $.

The system does not contain any equality.

cs_out1 The first output constraint system.
cs_out2 The second output constraint system, if any: it may be an alias for cs_out1.

The allocation of variable indices in the output constraint systems cs_out1 and cs_out2 is as follows, where $m$ is the number of constraints in cs:

  • $ \mu_1, \ldots, \mu_n $ go onto space dimensions $ 0, \ldots, n-1 $;
  • $ \mu_0$ goes onto space dimension $ n $;
  • $ y_1, \ldots, y_m $ go onto space dimensions $ n+1, \ldots, n+m $;

if we use the same constraint system, that is &cs_out1 == &cs_out2, then

  • $ z_1, ..., z_m, z_{m+1}, z_{m+2} $ go onto space dimensions $ n+m+1, ..., n+2*m+2 $;

otherwise

  • $ z_1, ..., z_m, z_{m+1}, z_{m+2} $ go onto space dimensions $ n+1, ..., n+m+2 $.

Definition at line 141 of file termination.cc.

00143                          {m+1}, z_{m+2} \f$ go onto space dimensions
00144     \f$ n+1, ..., n+m+2 \f$.
00145 */
00146 void
00147 fill_constraint_systems_MS(const Constraint_System& cs,
00148                            Constraint_System& cs_out1,
00149                            Constraint_System& cs_out2) {
00150   PPL_ASSERT(cs.space_dimension() % 2 == 0);
00151   const dimension_type n = cs.space_dimension() / 2;
00152   const dimension_type m = std::distance(cs.begin(), cs.end());
00153 
00154 #if PRINT_DEBUG_INFO
00155   Variable::output_function_type* p_default_output_function
00156     = Variable::get_output_function();
00157   Variable::set_output_function(output_function_MS);
00158 
00159   output_function_MS_n = n;
00160   output_function_MS_m = m;
00161 
00162   std::cout << "*** cs ***" << std::endl;
00163   output_function_MS_which = 0;
00164   using namespace IO_Operators;
00165   std::cout << cs << std::endl;
00166 #endif
00167 
00168   dimension_type y_begin = n+1;
00169   dimension_type z_begin = y_begin + ((&cs_out1 == &cs_out2) ? m : 0);
00170 
00171   // Make sure linear expressions are not reallocated multiple times.
00172   Linear_Expression y_le(0*Variable(y_begin + m - 1));
00173   Linear_Expression z_le(0*Variable(z_begin + m + 2 - 1));
00174   std::vector<Linear_Expression> y_les(2*n, y_le);
00175   std::vector<Linear_Expression> z_les(2*n + 1, z_le);
00176 
00177   dimension_type y = y_begin;
00178   dimension_type z = z_begin;
00179   for (Constraint_System::const_iterator i = cs.begin(),
00180          cs_end = cs.end(); i != cs_end; ++i) {
00181     Variable vy(y);
00182     Variable vz(z);
00183     ++y;
00184     ++z;
00185     cs_out1.insert(vy >= 0);
00186     cs_out2.insert(vz >= 0);
00187     const Constraint& c_i = *i;
00188     Coefficient_traits::const_reference b_i = c_i.inhomogeneous_term();
00189     if (b_i != 0) {
00190       // Note that b_i is to the left ot the relation sign, hence here
00191       // we have -= and not += just to avoid negating b_i.
00192       sub_mul_assign(y_le, b_i, vy);
00193       sub_mul_assign(z_le, b_i, vz);
00194     }
00195     for (dimension_type j = 2*n; j-- > 0; ) {
00196       Coefficient_traits::const_reference a_i_j = c_i.coefficient(Variable(j));
00197       if (a_i_j != 0) {
00198         add_mul_assign(y_les[j], a_i_j, vy);
00199         add_mul_assign(z_les[j], a_i_j, vz);
00200       }
00201     }
00202   }
00203   z_le += Variable(z);
00204   z_les[2*n] += Variable(z);
00205   cs_out2.insert(Variable(z) >= 0);
00206   ++z;
00207   z_le -= Variable(z);
00208   z_les[2*n] -= Variable(z);
00209   cs_out2.insert(Variable(z) >= 0);
00210   cs_out1.insert(y_le >= 1);
00211   cs_out2.insert(z_le >= 0);
00212   dimension_type j = 2*n;
00213   while (j-- > n) {
00214     cs_out1.insert(y_les[j] == Variable(j-n));
00215     cs_out2.insert(z_les[j] == Variable(j-n));
00216   }
00217   ++j;
00218   while (j-- > 0) {
00219     cs_out1.insert(y_les[j] == -Variable(j));
00220     cs_out2.insert(z_les[j] == 0);
00221   }
00222   cs_out2.insert(z_les[2*n] == Variable(n));
00223 
00224 #if PRINT_DEBUG_INFO
00225   if (&cs_out1 == &cs_out2) {
00226     std::cout << "*** cs_mip ***" << std::endl;
00227     output_function_MS_which = 3;
00228     using namespace IO_Operators;
00229     std::cout << cs_mip << std::endl;
00230   }
00231   else {
00232     std::cout << "*** cs_out1 ***" << std::endl;
00233     output_function_MS_which = 1;
00234     using namespace IO_Operators;
00235     std::cout << cs_out1 << std::endl;
00236 
00237     std::cout << "*** cs_out2 ***" << std::endl;
00238     output_function_MS_which = 2;
00239     using namespace IO_Operators;

bool Parma_Polyhedra_Library::Implementation::Termination::one_affine_ranking_function_MS ( const Constraint_System &  cs,
Generator &  mu 
)

Definition at line 493 of file termination.cc.

00499                                                                            {
00500   Constraint_System cs_mip;
00501   fill_constraint_systems_MS(cs, cs_mip, cs_mip);
00502 
00503   MIP_Problem mip = MIP_Problem(cs_mip.space_dimension(), cs_mip);
00504   if (!mip.is_satisfiable())
00505     return false;
00506 
00507   Generator fp = mip.feasible_point();
00508   PPL_ASSERT(fp.is_point());
00509   Linear_Expression le;
00510   const dimension_type n = cs.space_dimension() / 2;
00511   for (dimension_type i = n+1; i-- > 0; ) {

bool Parma_Polyhedra_Library::Implementation::Termination::one_affine_ranking_function_PR ( const Constraint_System &  cs_before,
const Constraint_System &  cs_after,
Generator &  mu 
)

Definition at line 642 of file termination.cc.

00650                                               {
00651   Constraint_System cs_mip;
00652   Linear_Expression le_ineq;
00653   fill_constraint_system_PR(cs_before, cs_after, cs_mip, le_ineq);
00654 
00655 #if PRINT_DEBUG_INFO
00656   Variable::output_function_type* p_default_output_function
00657     = Variable::get_output_function();
00658   Variable::set_output_function(output_function_PR);
00659 
00660   output_function_PR_r = distance(cs_before.begin(), cs_before.end());
00661   output_function_PR_s = distance(cs_after.begin(), cs_after.end());
00662 
00663   std::cout << "*** cs_mip ***" << std::endl;
00664   using namespace IO_Operators;
00665   std::cout << cs_mip << std::endl;
00666   std::cout << "*** le_ineq ***" << std::endl;
00667   std::cout << le_ineq << std::endl;
00668 
00669   Variable::set_output_function(p_default_output_function);
00670 #endif
00671 
00672   // Turn minimization problem into satisfiability.
00673   cs_mip.insert(le_ineq <= -1);
00674 
00675   MIP_Problem mip(cs_mip.space_dimension(), cs_mip);
00676   if (!mip.is_satisfiable())
00677     return false;
00678 
00679   Generator fp = mip.feasible_point();
00680   PPL_ASSERT(fp.is_point());
00681 
00682   // u_3 corresponds to space dimensions 0, ..., s - 1.
00683   const dimension_type n = cs_before.space_dimension();
00684   Linear_Expression le;
00685   // mu_0 is zero: do this first to avoid reallocations.
00686   le += 0*Variable(n);
00687   // Multiply u_3 by E'_C to obtain mu_1, ..., mu_n.
00688   dimension_type row_index = 0;
00689   PPL_DIRTY_TEMP_COEFFICIENT(k);
00690   for (Constraint_System::const_iterator i = cs_after.begin(),
00691          cs_after_end = cs_after.end();
00692        i != cs_after_end;
00693        ++i, ++row_index) {
00694     Variable vi(row_index);
00695     Coefficient_traits::const_reference fp_i = fp.coefficient(vi);
00696     const Constraint& c_i = *i;
00697     for (dimension_type j = n; j-- > 0; ) {
00698       Variable vj(j);
00699       k = fp_i * c_i.coefficient(vj);
00700       sub_mul_assign(le, k, vj);

bool Parma_Polyhedra_Library::Implementation::Termination::one_affine_ranking_function_PR_original ( const Constraint_System &  cs,
Generator &  mu 
)

Definition at line 703 of file termination.cc.

Referenced by Parma_Polyhedra_Library::one_affine_ranking_function_PR().

00710                                                        {
00711   PPL_ASSERT(cs.space_dimension() % 2 == 0);
00712   const dimension_type n = cs.space_dimension() / 2;
00713   const dimension_type m = std::distance(cs.begin(), cs.end());
00714 
00715   Constraint_System cs_mip;
00716   Linear_Expression le_ineq;
00717   fill_constraint_system_PR_original(cs, cs_mip, le_ineq);
00718 
00719 #if PRINT_DEBUG_INFO
00720   std::cout << "*** cs_mip ***" << std::endl;
00721   using namespace IO_Operators;
00722   std::cout << cs_mip << std::endl;
00723   std::cout << "*** le_ineq ***" << std::endl;
00724   std::cout << le_ineq << std::endl;
00725 #endif
00726 
00727   // Turn minimization problem into satisfiability.
00728   cs_mip.insert(le_ineq <= -1);
00729 
00730   MIP_Problem mip = MIP_Problem(cs_mip.space_dimension(), cs_mip);
00731   if (!mip.is_satisfiable())
00732     return false;
00733 
00734   Generator fp = mip.feasible_point();
00735   PPL_ASSERT(fp.is_point());
00736   Linear_Expression le;
00737   // mu_0 is zero: do this first to avoid reallocations.
00738   le += 0*Variable(n);
00739   // Multiply -lambda_2 by A' to obtain mu_1, ..., mu_n.
00740   // lambda_2 corresponds to space dimensions m, ..., 2*m - 1.
00741   dimension_type row_index = m;
00742   PPL_DIRTY_TEMP_COEFFICIENT(k);
00743   for (Constraint_System::const_iterator i = cs.begin(),
00744          cs_end = cs.end(); i != cs_end; ++i, ++row_index) {
00745     Variable lambda_2(row_index);
00746     Coefficient_traits::const_reference fp_i = fp.coefficient(lambda_2);
00747     if (fp_i != 0) {
00748       const Constraint& c_i = *i;
00749       for (dimension_type j = n; j-- > 0; ) {
00750         Variable vj(j);
00751         Coefficient_traits::const_reference Ap_ij = c_i.coefficient(vj);
00752         k = fp_i * Ap_ij;
00753         sub_mul_assign(le, k, vj);
00754       }

void Parma_Polyhedra_Library::Implementation::Termination::shift_unprimed_variables ( Constraint_System &  cs  ) 

Definition at line 82 of file termination.cc.

Referenced by assign_all_inequalities_approximation().

00088                                                 {
00089   const dimension_type cs_space_dim = cs.space_dimension();
00090   Constraint_System cs_shifted;
00091   for (Constraint_System::const_iterator i = cs.begin(),
00092          cs_end = cs.end(); i != cs_end; ++i) {
00093     const Constraint& c_i = *i;
00094     Linear_Expression le_i_shifted;
00095     for (dimension_type j = cs_space_dim; j-- > 0; ) {
00096       Coefficient_traits::const_reference a_i_j
00097         = c_i.coefficient(Variable(j));
00098       if (a_i_j != 0)
00099         add_mul_assign(le_i_shifted, a_i_j, Variable(cs_space_dim + j));

bool Parma_Polyhedra_Library::Implementation::Termination::termination_test_MS ( const Constraint_System &  cs  ) 

Definition at line 484 of file termination.cc.

00490                                                  {

bool Parma_Polyhedra_Library::Implementation::Termination::termination_test_PR ( const Constraint_System &  cs_before,
const Constraint_System &  cs_after 
)

Definition at line 611 of file termination.cc.

00618                                                        {
00619   Constraint_System cs_mip;
00620   Linear_Expression le_ineq;
00621   fill_constraint_system_PR(cs_before, cs_after, cs_mip, le_ineq);
00622 
00623 #if PRINT_DEBUG_INFO
00624   Variable::output_function_type* p_default_output_function
00625     = Variable::get_output_function();
00626   Variable::set_output_function(output_function_PR);
00627 
00628   output_function_PR_r = distance(cs_before.begin(), cs_before.end());
00629   output_function_PR_s = distance(cs_after.begin(), cs_after.end());
00630 
00631   std::cout << "*** cs_mip ***" << std::endl;
00632   using namespace IO_Operators;
00633   std::cout << cs_mip << std::endl;
00634   std::cout << "*** le_ineq ***" << std::endl;
00635   std::cout << le_ineq << std::endl;
00636 
00637   Variable::set_output_function(p_default_output_function);
00638 #endif
00639 

bool Parma_Polyhedra_Library::Implementation::Termination::termination_test_PR_original ( const Constraint_System &  cs  ) 

Definition at line 596 of file termination.cc.

Referenced by Parma_Polyhedra_Library::termination_test_PR().

00602                                                           {
00603   PPL_ASSERT(cs.space_dimension() % 2 == 0);
00604 
00605   Constraint_System cs_mip;
00606   Linear_Expression le_ineq;
00607   fill_constraint_system_PR_original(cs, cs_mip, le_ineq);
00608 

Generated on Sun Feb 27 16:20:33 2011 for PPL by  doxygen 1.6.3