PPL  1.2
Parma_Polyhedra_Library::Implementation::Termination Namespace Reference

Functions

void assign_all_inequalities_approximation (const Constraint_System &cs_in, Constraint_System &cs_out)
 
template<>
void assign_all_inequalities_approximation (const C_Polyhedron &ph, Constraint_System &cs)
 
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. More...
 
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. More...
 
void fill_constraint_system_PR_original (const Constraint_System &cs, Constraint_System &cs_out, Linear_Expression &le_out)
 
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_original (const Constraint_System &cs)
 
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)
 
bool one_affine_ranking_function_PR_original (const Constraint_System &cs, Generator &mu)
 
void all_affine_ranking_functions_PR (const Constraint_System &cs_before, const Constraint_System &cs_after, NNC_Polyhedron &mu_space)
 
void all_affine_ranking_functions_PR_original (const Constraint_System &cs, NNC_Polyhedron &mu_space)
 
template<typename PSET >
void assign_all_inequalities_approximation (const PSET &pset, Constraint_System &cs)
 

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.

References Parma_Polyhedra_Library::Polyhedron::add_space_dimensions_and_embed(), fill_constraint_systems_MS(), Parma_Polyhedra_Library::Variable::get_output_function(), Parma_Polyhedra_Library::Polyhedron::m_swap(), Parma_Polyhedra_Library::Polyhedron::minimized_constraints(), Parma_Polyhedra_Library::Implementation::num_constraints(), Parma_Polyhedra_Library::Polyhedron::remove_higher_space_dimensions(), Parma_Polyhedra_Library::Variable::set_output_function(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().

Referenced by Parma_Polyhedra_Library::all_affine_quasi_ranking_functions_MS(), and Parma_Polyhedra_Library::all_affine_quasi_ranking_functions_MS_2().

560  {
561  Constraint_System cs_out1;
562  Constraint_System cs_out2;
563  fill_constraint_systems_MS(cs, cs_out1, cs_out2);
564 
565  C_Polyhedron ph1(cs_out1);
566  C_Polyhedron ph2(cs_out2);
567  const dimension_type n = cs.space_dimension() / 2;
568  ph1.remove_higher_space_dimensions(n);
569  ph1.add_space_dimensions_and_embed(1);
570  ph2.remove_higher_space_dimensions(n+1);
571 
572 #if PRINT_DEBUG_INFO
573  Variable::output_function_type* p_default_output_function
574  = Variable::get_output_function();
575  Variable::set_output_function(output_function_MS);
576 
577  output_function_MS_n = n;
578  output_function_MS_m = num_constraints(cs);
579 
580  std::cout << "*** ph1 projected ***" << std::endl;
581  output_function_MS_which = 4;
582  using namespace IO_Operators;
583  std::cout << ph1.minimized_constraints() << std::endl;
584 
585  std::cout << "*** ph2 projected ***" << std::endl;
586  std::cout << ph2.minimized_constraints() << std::endl;
587 
588  Variable::set_output_function(p_default_output_function);
589 #endif
590 
591  decreasing_mu_space.m_swap(ph1);
592  bounded_mu_space.m_swap(ph2);
593 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
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 ...
Definition: termination.cc:134
dimension_type num_constraints(const Constraint_System &cs)
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.

References Parma_Polyhedra_Library::Polyhedron::add_space_dimensions_and_embed(), fill_constraint_systems_MS(), Parma_Polyhedra_Library::Variable::get_output_function(), Parma_Polyhedra_Library::Polyhedron::intersection_assign(), Parma_Polyhedra_Library::Polyhedron::m_swap(), Parma_Polyhedra_Library::Polyhedron::minimized_constraints(), Parma_Polyhedra_Library::Implementation::num_constraints(), Parma_Polyhedra_Library::Polyhedron::remove_higher_space_dimensions(), Parma_Polyhedra_Library::Variable::set_output_function(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().

Referenced by Parma_Polyhedra_Library::all_affine_ranking_functions_MS(), and Parma_Polyhedra_Library::all_affine_ranking_functions_MS_2().

515  {
516  Constraint_System cs_out1;
517  Constraint_System cs_out2;
518  fill_constraint_systems_MS(cs, cs_out1, cs_out2);
519 
520  C_Polyhedron ph1(cs_out1);
521  C_Polyhedron ph2(cs_out2);
522  const dimension_type n = cs.space_dimension() / 2;
523  ph1.remove_higher_space_dimensions(n);
524  ph1.add_space_dimensions_and_embed(1);
525  ph2.remove_higher_space_dimensions(n+1);
526 
527 #if PRINT_DEBUG_INFO
528  Variable::output_function_type* p_default_output_function
529  = Variable::get_output_function();
530  Variable::set_output_function(output_function_MS);
531 
532  output_function_MS_n = n;
533  output_function_MS_m = num_constraints(cs);
534 
535  std::cout << "*** ph1 projected ***" << std::endl;
536  output_function_MS_which = 4;
537  using namespace IO_Operators;
538  std::cout << ph1.minimized_constraints() << std::endl;
539 
540  std::cout << "*** ph2 projected ***" << std::endl;
541  std::cout << ph2.minimized_constraints() << std::endl;
542 #endif
543 
544  ph1.intersection_assign(ph2);
545 
546 #if PRINT_DEBUG_INFO
547  std::cout << "*** intersection ***" << std::endl;
548  using namespace IO_Operators;
549  std::cout << ph1.minimized_constraints() << std::endl;
550 
551  Variable::set_output_function(p_default_output_function);
552 #endif
553 
554  mu_space.m_swap(ph1);
555 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
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 ...
Definition: termination.cc:134
dimension_type num_constraints(const Constraint_System &cs)
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 656 of file termination.cc.

References Parma_Polyhedra_Library::Termination_Helpers::all_affine_ranking_functions_PR().

Referenced by Parma_Polyhedra_Library::all_affine_ranking_functions_PR_2().

658  {
660  mu_space);
661 }
void all_affine_ranking_functions_PR(const Constraint_System &cs_before, const Constraint_System &cs_after, NNC_Polyhedron &mu_space)
Definition: termination.cc:656
void Parma_Polyhedra_Library::Implementation::Termination::all_affine_ranking_functions_PR_original ( const Constraint_System cs,
NNC_Polyhedron mu_space 
)
void Parma_Polyhedra_Library::Implementation::Termination::assign_all_inequalities_approximation ( const Constraint_System cs_in,
Constraint_System cs_out 
)

Definition at line 35 of file termination.cc.

References Parma_Polyhedra_Library::Constraint_System::begin(), c, Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Constraint::expression(), 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_ranking_functions_MS(), 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_PR(), Parma_Polyhedra_Library::one_affine_ranking_function_PR_2(), Parma_Polyhedra_Library::termination_test_MS(), Parma_Polyhedra_Library::termination_test_PR(), and Parma_Polyhedra_Library::termination_test_PR_2().

36  {
37  if (cs_in.has_strict_inequalities() || cs_in.has_equalities()) {
38  // Here we have some strict inequality and/or equality constraints:
39  // translate them into non-strict inequality constraints.
40  for (Constraint_System::const_iterator i = cs_in.begin(),
41  i_end = cs_in.end(); i != i_end; ++i) {
42  const Constraint& c = *i;
43  if (c.is_equality()) {
44  // Insert the two corresponding opposing inequalities.
45  const Linear_Expression expr(c.expression());
46  cs_out.insert(expr >= 0);
47  cs_out.insert(expr <= 0);
48  }
49  else if (c.is_strict_inequality()) {
50  // Insert the non-strict approximation.
51  const Linear_Expression expr(c.expression());
52  cs_out.insert(expr >= 0);
53  }
54  else {
55  // Insert as is.
56  cs_out.insert(c);
57  }
58  }
59  }
60  else {
61  // No strict inequality and no equality constraints.
62  cs_out = cs_in;
63  }
64 }
Coefficient c
Definition: PIP_Tree.cc:64
template<>
void Parma_Polyhedra_Library::Implementation::Termination::assign_all_inequalities_approximation ( const C_Polyhedron ph,
Constraint_System cs 
)

Definition at line 68 of file termination.cc.

References Parma_Polyhedra_Library::Constraint_System::begin(), c, Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Constraint::expression(), Parma_Polyhedra_Library::Constraint_System::has_equalities(), Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::Constraint::is_equality(), and Parma_Polyhedra_Library::Polyhedron::minimized_constraints().

69  {
70  const Constraint_System& ph_cs = ph.minimized_constraints();
71  if (ph_cs.has_equalities()) {
72  // Translate equalities into inequalities.
73  for (Constraint_System::const_iterator i = ph_cs.begin(),
74  i_end = ph_cs.end(); i != i_end; ++i) {
75  const Constraint& c = *i;
76  if (c.is_equality()) {
77  // Insert the two corresponding opposing inequalities.
78  const Linear_Expression expr(c.expression());
79  cs.insert(expr >= 0);
80  cs.insert(expr <= 0);
81  }
82  else {
83  // Insert as is.
84  cs.insert(c);
85  }
86  }
87  }
88  else {
89  // No equality constraints (and no strict inequalities).
90  cs = ph_cs;
91  }
92 }
Coefficient c
Definition: PIP_Tree.cc:64
template<typename PSET >
void Parma_Polyhedra_Library::Implementation::Termination::assign_all_inequalities_approximation ( const PSET &  pset,
Constraint_System cs 
)
inline
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_beforeThe 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_afterThe 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_outThe 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_outThe expression to be minimized in the context of cs_out: a value of $ -1 $ or less entails termination.

Definition at line 348 of file termination.cc.

References Parma_Polyhedra_Library::add_mul_assign(), Parma_Polyhedra_Library::Expression_Adapter< T >::begin(), Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Expression_Hide_Last< T >::end(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Expression_Adapter< T >::inhomogeneous_term(), Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::Expression_Hide_Last< T >::lower_bound(), Parma_Polyhedra_Library::Implementation::num_constraints(), row_index, Parma_Polyhedra_Library::Linear_Expression::set_space_dimension(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), and Parma_Polyhedra_Library::sub_mul_assign().

Referenced by Parma_Polyhedra_Library::Termination_Helpers::all_affine_ranking_functions_PR(), Parma_Polyhedra_Library::Termination_Helpers::one_affine_ranking_function_PR(), and termination_test_PR().

351  {
352  PPL_ASSERT(cs_after.space_dimension() % 2 == 0);
353  PPL_ASSERT(2*cs_before.space_dimension() == cs_after.space_dimension());
354  const dimension_type n = cs_before.space_dimension();
355  const dimension_type r = num_constraints(cs_before);
356  const dimension_type s = num_constraints(cs_after);
357  const dimension_type m = r + s;
358 
359  // Make sure linear expressions are not reallocated multiple times.
360  if (m > 0) {
361  le_out.set_space_dimension(m + r);
362  }
363  std::vector<Linear_Expression> les_eq(2*n, le_out);
364 
366  for (Constraint_System::const_iterator i = cs_before.begin(),
367  cs_before_end = cs_before.end();
368  i != cs_before_end;
369  ++i, ++row_index) {
370  const Variable u1_i(m + row_index);
371  const Variable u2_i(s + row_index);
372  const Constraint::expr_type e_i = i->expression();
373  for (Constraint::expr_type::const_iterator
374  j = e_i.begin(), j_end = e_i.end(); j != j_end; ++j) {
375  Coefficient_traits::const_reference A_ij_B = *j;
376  const Variable v = j.variable();
377  // (u1 - u2) A_B, in the context of j-th constraint.
378  add_mul_assign(les_eq[v.id()], A_ij_B, u1_i);
379  sub_mul_assign(les_eq[v.id()], A_ij_B, u2_i);
380  // u2 A_B, in the context of (j+n)-th constraint.
381  add_mul_assign(les_eq[v.id() + n], A_ij_B, u2_i);
382  }
383  Coefficient_traits::const_reference b_B = e_i.inhomogeneous_term();
384  if (b_B != 0) {
385  // u2 b_B, in the context of the strict inequality constraint.
386  add_mul_assign(le_out, b_B, u2_i);
387  }
388  }
389 
390  row_index = 0;
391  for (Constraint_System::const_iterator i = cs_after.begin(),
392  cs_after_end = cs_after.end();
393  i != cs_after_end;
394  ++i, ++row_index) {
395  const Variable u3_i(row_index);
396  const Constraint::expr_type e_i = i->expression();
397  for (Constraint::expr_type::const_iterator
398  j = e_i.lower_bound(Variable(n)),
399  j_end = e_i.end(); j != j_end; ++j) {
400  Coefficient_traits::const_reference A_ij_C = *j;
401  const Variable v = j.variable();
402  // - u3 A_C, in the context of the j-th constraint.
403  sub_mul_assign(les_eq[v.id() - n], A_ij_C, u3_i);
404  // u3 A_C, in the context of the (j+n)-th constraint.
405  add_mul_assign(les_eq[v.id()], A_ij_C, u3_i);
406  }
407  for (Constraint::expr_type::const_iterator j = e_i.begin(),
408  j_end = e_i.lower_bound(Variable(n)); j != j_end; ++j) {
409  Coefficient_traits::const_reference Ap_ij_C = *j;
410  // u3 Ap_C, in the context of the (j+n)-th constraint.
411  add_mul_assign(les_eq[j.variable().id() + n], Ap_ij_C, u3_i);
412  }
413  Coefficient_traits::const_reference b_C = e_i.inhomogeneous_term();
414  if (b_C != 0) {
415  // u3 b_C, in the context of the strict inequality constraint.
416  add_mul_assign(le_out, b_C, u3_i);
417  }
418  }
419 
420  // Add the nonnegativity constraints for u_1, u_2 and u_3.
421  for (dimension_type i = s + 2*r; i-- > 0; ) {
422  cs_out.insert(Variable(i) >= 0);
423  }
424 
425  for (dimension_type j = 2*n; j-- > 0; ) {
426  cs_out.insert(les_eq[j] == 0);
427  }
428 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void add_mul_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
Assigns to x the value x + y * z.
void sub_mul_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
Assigns to x the value x - y * z.
dimension_type row_index
Definition: PIP_Tree.cc:615
dimension_type num_constraints(const Constraint_System &cs)
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 431 of file termination.cc.

References Parma_Polyhedra_Library::add_mul_assign(), Parma_Polyhedra_Library::Expression_Adapter< T >::begin(), Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Expression_Hide_Last< T >::end(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Expression_Adapter< T >::inhomogeneous_term(), Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::Expression_Hide_Last< T >::lower_bound(), Parma_Polyhedra_Library::Implementation::num_constraints(), row_index, Parma_Polyhedra_Library::Linear_Expression::set_space_dimension(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), and Parma_Polyhedra_Library::sub_mul_assign().

Referenced by Parma_Polyhedra_Library::Termination_Helpers::all_affine_ranking_functions_PR_original(), Parma_Polyhedra_Library::Termination_Helpers::one_affine_ranking_function_PR_original(), and termination_test_PR_original().

433  {
434  PPL_ASSERT(cs.space_dimension() % 2 == 0);
435  const dimension_type n = cs.space_dimension() / 2;
436  const dimension_type m = num_constraints(cs);
437 
438  // Make sure linear expressions are not reallocated multiple times.
439  if (m > 0) {
440  le_out.set_space_dimension(2*m);
441  }
442  std::vector<Linear_Expression> les_eq(3*n, le_out);
443 
445  for (Constraint_System::const_iterator i = cs.begin(),
446  cs_end = cs.end(); i != cs_end; ++i, ++row_index) {
447  const Constraint::expr_type e_i = i->expression();
448  const Variable lambda1_i(row_index);
449  const Variable lambda2_i(m + row_index);
450  for (Constraint::expr_type::const_iterator j = e_i.begin(),
451  j_end = e_i.lower_bound(Variable(n)); j != j_end; ++j) {
452  Coefficient_traits::const_reference Ap_ij = *j;
453  const Variable v = j.variable();
454  // lambda_1 A'
455  add_mul_assign(les_eq[v.id()], Ap_ij, lambda1_i);
456  // lambda_2 A'
457  add_mul_assign(les_eq[v.id()+n+n], Ap_ij, lambda2_i);
458  }
459  for (Constraint::expr_type::const_iterator
460  j = e_i.lower_bound(Variable(n)),
461  j_end = e_i.end(); j != j_end; ++j) {
462  Coefficient_traits::const_reference A_ij = *j;
463  const Variable v = j.variable();
464  // (lambda_1 - lambda_2) A
465  add_mul_assign(les_eq[v.id()], A_ij, lambda1_i);
466  sub_mul_assign(les_eq[v.id()], A_ij, lambda2_i);
467  // lambda_2 A
468  add_mul_assign(les_eq[v.id()+n], A_ij, lambda2_i);
469  }
470  Coefficient_traits::const_reference b = e_i.inhomogeneous_term();
471  if (b != 0) {
472  // lambda2 b
473  add_mul_assign(le_out, b, lambda2_i);
474  }
475  }
476 
477  // Add the non-negativity constraints for lambda_1 and lambda_2.
478  for (dimension_type i = 2*m; i-- > 0; ) {
479  cs_out.insert(Variable(i) >= 0);
480  }
481 
482  for (dimension_type j = 3*n; j-- > 0; ) {
483  cs_out.insert(les_eq[j] == 0);
484  }
485 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void add_mul_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
Assigns to x the value x + y * z.
void sub_mul_assign(Checked_Number< T, Policy > &x, const Checked_Number< T, Policy > &y, const Checked_Number< T, Policy > &z)
Assigns to x the value x - y * z.
dimension_type row_index
Definition: PIP_Tree.cc:615
dimension_type num_constraints(const Constraint_System &cs)
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
csThe 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_out1The first output constraint system.
cs_out2The 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 134 of file termination.cc.

References Parma_Polyhedra_Library::add_mul_assign(), Parma_Polyhedra_Library::Expression_Adapter< T >::begin(), Parma_Polyhedra_Library::Constraint_System::begin(), Parma_Polyhedra_Library::Expression_Hide_Last< T >::end(), Parma_Polyhedra_Library::Constraint_System::end(), Parma_Polyhedra_Library::Constraint::expression(), Parma_Polyhedra_Library::Variable::get_output_function(), Parma_Polyhedra_Library::Variable::id(), Parma_Polyhedra_Library::Constraint::inhomogeneous_term(), Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::Implementation::num_constraints(), Parma_Polyhedra_Library::Variable::set_output_function(), Parma_Polyhedra_Library::Linear_Expression::set_space_dimension(), Parma_Polyhedra_Library::Constraint_System::space_dimension(), and Parma_Polyhedra_Library::sub_mul_assign().

Referenced by all_affine_quasi_ranking_functions_MS(), all_affine_ranking_functions_MS(), one_affine_ranking_function_MS(), and termination_test_MS().

136  {
137  PPL_ASSERT(cs.space_dimension() % 2 == 0);
138  const dimension_type n = cs.space_dimension() / 2;
139  const dimension_type m = num_constraints(cs);
140 
141 #if PRINT_DEBUG_INFO
142  Variable::output_function_type* p_default_output_function
143  = Variable::get_output_function();
144  Variable::set_output_function(output_function_MS);
145 
146  output_function_MS_n = n;
147  output_function_MS_m = m;
148 
149  std::cout << "*** cs ***" << std::endl;
150  output_function_MS_which = 0;
151  using namespace IO_Operators;
152  std::cout << cs << std::endl;
153 #endif
154 
155  const dimension_type y_begin = n+1;
156  const dimension_type z_begin = y_begin + ((&cs_out1 == &cs_out2) ? m : 0);
157 
158  // Make sure linear expressions have the correct space dimension.
159  Linear_Expression y_le;
160  y_le.set_space_dimension(y_begin + m);
161  Linear_Expression z_le;
162  z_le.set_space_dimension(z_begin + m + 2);
163  std::vector<Linear_Expression> y_les(2*n, y_le);
164  std::vector<Linear_Expression> z_les(2*n + 1, z_le);
165 
166  dimension_type y = y_begin;
167  dimension_type z = z_begin;
168  for (Constraint_System::const_iterator i = cs.begin(),
169  cs_end = cs.end(); i != cs_end; ++i) {
170  const Variable v_y(y);
171  const Variable v_z(z);
172  ++y;
173  ++z;
174  cs_out1.insert(v_y >= 0);
175  cs_out2.insert(v_z >= 0);
176  const Constraint& c_i = *i;
177  Coefficient_traits::const_reference b_i = c_i.inhomogeneous_term();
178  if (b_i != 0) {
179  // Note that b_i is to the left ot the relation sign, hence here
180  // we have -= and not += just to avoid negating b_i.
181  sub_mul_assign(y_le, b_i, v_y);
182  sub_mul_assign(z_le, b_i, v_z);
183  }
184  for (Constraint::expr_type::const_iterator j = c_i.expression().begin(),
185  j_end = c_i.expression().end(); j != j_end; ++j) {
186  Coefficient_traits::const_reference a_i_j = *j;
187  const Variable v = j.variable();
188  add_mul_assign(y_les[v.id()], a_i_j, v_y);
189  add_mul_assign(z_les[v.id()], a_i_j, v_z);
190  }
191  }
192  z_le += Variable(z);
193  z_les[2*n] += Variable(z);
194  cs_out2.insert(Variable(z) >= 0);
195  ++z;
196  z_le -= Variable(z);
197  z_les[2*n] -= Variable(z);
198  cs_out2.insert(Variable(z) >= 0);
199  cs_out1.insert(y_le >= 1);
200  cs_out2.insert(z_le >= 0);
201  dimension_type j = 2*n;
202  while (j-- > n) {
203  cs_out1.insert(y_les[j] == Variable(j-n));
204  cs_out2.insert(z_les[j] == Variable(j-n));
205  }
206  ++j;
207  while (j-- > 0) {
208  cs_out1.insert(y_les[j] == -Variable(j));
209  cs_out2.insert(z_les[j] == 0);
210  }
211  cs_out2.insert(z_les[2*n] == Variable(n));
212 
213 #if PRINT_DEBUG_INFO
214  if (&cs_out1 == &cs_out2) {
215  std::cout << "*** cs_mip ***" << std::endl;
216  output_function_MS_which = 3;
217  using namespace IO_Operators;
218  std::cout << cs_mip << std::endl;
219  }
220  else {
221  std::cout << "*** cs_out1 ***" << std::endl;
222  output_function_MS_which = 1;
223  using namespace IO_Operators;
224  std::cout << cs_out1 << std::endl;
225 
226  std::cout << "*** cs_out2 ***" << std::endl;
227  output_function_MS_which = 2;
228  using namespace IO_Operators;
229  std::cout << cs_out2 << std::endl;
230  }
231 
232  Variable::set_output_function(p_default_output_function);
233 #endif
234 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
void add_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
dimension_type num_constraints(const Constraint_System &cs)
void sub_mul_assign(GMP_Integer &x, const GMP_Integer &y, const GMP_Integer &z)
bool Parma_Polyhedra_Library::Implementation::Termination::one_affine_ranking_function_MS ( const Constraint_System cs,
Generator mu 
)

Definition at line 497 of file termination.cc.

References Parma_Polyhedra_Library::Generator::divisor(), Parma_Polyhedra_Library::Generator::expression(), Parma_Polyhedra_Library::MIP_Problem::feasible_point(), fill_constraint_systems_MS(), Parma_Polyhedra_Library::Generator::is_point(), Parma_Polyhedra_Library::MIP_Problem::is_satisfiable(), Parma_Polyhedra_Library::Boundary_NS::le(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().

Referenced by Parma_Polyhedra_Library::one_affine_ranking_function_MS(), and Parma_Polyhedra_Library::one_affine_ranking_function_MS_2().

497  {
498  Constraint_System cs_mip;
499  fill_constraint_systems_MS(cs, cs_mip, cs_mip);
500 
501  const MIP_Problem mip = MIP_Problem(cs_mip.space_dimension(), cs_mip);
502  if (!mip.is_satisfiable()) {
503  return false;
504  }
505  const Generator fp = mip.feasible_point();
506  PPL_ASSERT(fp.is_point());
507  const dimension_type n = cs.space_dimension() / 2;
508  const Linear_Expression le(fp.expression(), n + 1);
509  mu = point(le, fp.divisor());
510  return true;
511 }
size_t dimension_type
An unsigned integral type for representing space dimensions.
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 ...
Definition: termination.cc:134
Generator point(const Linear_Expression &e=Linear_Expression::zero(), Coefficient_traits::const_reference d=Coefficient_one(), Representation r=Generator::default_representation)
Shorthand for Generator::point(const Linear_Expression& e, Coefficient_traits::const_reference d...
bool le(Boundary_Type type1, const T1 &x1, const Info1 &info1, Boundary_Type type2, const T2 &x2, const Info2 &info2)
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.

Referenced by Parma_Polyhedra_Library::one_affine_ranking_function_PR_2().

644  {
645  return Termination_Helpers
646  ::one_affine_ranking_function_PR(cs_before, cs_after, mu);
647 }
bool one_affine_ranking_function_PR(const Constraint_System &cs_before, const Constraint_System &cs_after, Generator &mu)
Definition: termination.cc:642
bool Parma_Polyhedra_Library::Implementation::Termination::one_affine_ranking_function_PR_original ( const Constraint_System cs,
Generator mu 
)
bool Parma_Polyhedra_Library::Implementation::Termination::termination_test_MS ( const Constraint_System cs)

Definition at line 488 of file termination.cc.

References fill_constraint_systems_MS(), Parma_Polyhedra_Library::MIP_Problem::is_satisfiable(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().

Referenced by Parma_Polyhedra_Library::termination_test_MS(), and Parma_Polyhedra_Library::termination_test_MS_2().

488  {
489  Constraint_System cs_mip;
490  fill_constraint_systems_MS(cs, cs_mip, cs_mip);
491 
492  const MIP_Problem mip = MIP_Problem(cs_mip.space_dimension(), cs_mip);
493  return mip.is_satisfiable();
494 }
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 ...
Definition: termination.cc:134
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.

References fill_constraint_system_PR(), Parma_Polyhedra_Library::Variable::get_output_function(), Parma_Polyhedra_Library::Constraint_System::insert(), Parma_Polyhedra_Library::MIP_Problem::is_satisfiable(), Parma_Polyhedra_Library::Implementation::num_constraints(), Parma_Polyhedra_Library::Variable::set_output_function(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().

Referenced by Parma_Polyhedra_Library::termination_test_PR_2().

612  {
613  Constraint_System cs_mip;
614  Linear_Expression le_ineq;
615  fill_constraint_system_PR(cs_before, cs_after, cs_mip, le_ineq);
616 
617 #if PRINT_DEBUG_INFO
618  Variable::output_function_type* p_default_output_function
619  = Variable::get_output_function();
620  Variable::set_output_function(output_function_PR);
621 
622  output_function_PR_r = num_constraints(cs_before);
623  output_function_PR_s = num_constraints(cs_after);
624 
625  std::cout << "*** cs_mip ***" << std::endl;
626  using namespace IO_Operators;
627  std::cout << cs_mip << std::endl;
628  std::cout << "*** le_ineq ***" << std::endl;
629  std::cout << le_ineq << std::endl;
630 
631  Variable::set_output_function(p_default_output_function);
632 #endif
633 
634  // Turn minimization problem into satisfiability.
635  cs_mip.insert(le_ineq <= -1);
636 
637  const MIP_Problem mip(cs_mip.space_dimension(), cs_mip);
638  return mip.is_satisfiable();
639 }
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 terminatio...
Definition: termination.cc:348
dimension_type num_constraints(const Constraint_System &cs)
bool Parma_Polyhedra_Library::Implementation::Termination::termination_test_PR_original ( const Constraint_System cs)

Definition at line 596 of file termination.cc.

References fill_constraint_system_PR_original(), Parma_Polyhedra_Library::MIP_Problem::is_satisfiable(), and Parma_Polyhedra_Library::Constraint_System::space_dimension().

Referenced by Parma_Polyhedra_Library::termination_test_PR().

596  {
597  PPL_ASSERT(cs.space_dimension() % 2 == 0);
598 
599  Constraint_System cs_mip;
600  Linear_Expression le_ineq;
601  fill_constraint_system_PR_original(cs, cs_mip, le_ineq);
602 
603  // Turn minimization problem into satisfiability.
604  cs_mip.insert(le_ineq <= -1);
605 
606  const MIP_Problem mip(cs_mip.space_dimension(), cs_mip);
607  return mip.is_satisfiable();
608 }
void fill_constraint_system_PR_original(const Constraint_System &cs, Constraint_System &cs_out, Linear_Expression &le_out)
Definition: termination.cc:431