| 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 }
| 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 }
| 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);
| 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.
| cs_before | The input constraint system describing the state before the execution of the loop body, where variables indices are allocated as follows:
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:
The system does not contain any equality. | |
| cs_out | The output constraint system, where variables indices are allocated as follows:
|
The improved Podelski-Rybalchenko method described in the paper is based on a loop encoding of the form
where
,
,
,
,
. The corresponding system is:
where
,
,
. The space of ranking functions is then spanned by
.
In contrast, our encoding is of the form
where
,
,
,
and
. The corresponding system is:
where
,
,
. The space of ranking functions is then spanned by
.
| le_out | The expression to be minimized in the context of cs_out: a value of 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.
| cs | The input constraint system, where variables indices are allocated as follows:
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
is the number of constraints in cs:
go onto space dimensions
;
goes onto space dimension
;
go onto space dimensions
;if we use the same constraint system, that is &cs_out1 == &cs_out2, then
go onto space dimensions
;otherwise
go onto space dimensions
. 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.
| 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
1.6.3