00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <ppl-config.h>
00025
00026 #include "termination.defs.hh"
00027 #include "NNC_Polyhedron.defs.hh"
00028
00029 namespace Parma_Polyhedra_Library {
00030
00031 namespace Implementation {
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
00040
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
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
00051 cs_out.insert(Linear_Expression(c) >= 0);
00052 else
00053
00054 cs_out.insert(c);
00055 }
00056 }
00057 else
00058
00059 cs_out = cs_in;
00060 }
00061
00062 template <>
00063 void
00064 assign_all_inequalities_approximation(const C_Polyhedron& ph,
00065 Constraint_System& cs) {
00066 const Constraint_System& ph_cs = ph.minimized_constraints();
00067 if (ph_cs.has_equalities()) {
00068
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
00074 cs.insert(Linear_Expression(c) >= 0);
00075 cs.insert(Linear_Expression(c) <= 0);
00076 }
00077 else
00078
00079 cs.insert(c);
00080 }
00081 }
00082 else
00083
00084 cs = ph_cs;
00085 }
00086
00087 void
00088 shift_unprimed_variables(Constraint_System& cs) {
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));
00100 }
00101 le_i_shifted += c_i.inhomogeneous_term();
00102 cs_shifted.insert(le_i_shifted >= 0);
00103 }
00104 cs.swap(cs_shifted);
00105 }
00106
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
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
00191
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;
00240 std::cout << cs_out2 << std::endl;
00241 }
00242
00243 Variable::set_output_function(p_default_output_function);
00244 #endif
00245 }
00246
00358 void
00359 fill_constraint_system_PR(const Constraint_System& cs_before,
00360 const Constraint_System& cs_after,
00361 Constraint_System& cs_out,
00362 Linear_Expression& le_out) {
00363 PPL_ASSERT(cs_after.space_dimension() % 2 == 0);
00364 PPL_ASSERT(2*cs_before.space_dimension() == cs_after.space_dimension());
00365 const dimension_type n = cs_before.space_dimension();
00366 const dimension_type r = distance(cs_before.begin(), cs_before.end());
00367 const dimension_type s = distance(cs_after.begin(), cs_after.end());
00368 const dimension_type m = r + s;
00369
00370
00371 if (m > 0)
00372 le_out = 0 * Variable(m + r - 1);
00373 std::vector<Linear_Expression> les_eq(2*n, le_out);
00374
00375 dimension_type row_index = 0;
00376 for (Constraint_System::const_iterator i = cs_before.begin(),
00377 cs_before_end = cs_before.end();
00378 i != cs_before_end;
00379 ++i, ++row_index) {
00380 Variable u1_i(m + row_index);
00381 Variable u2_i(s + row_index);
00382 const Constraint& c_i = *i;
00383 for (dimension_type j = n; j-- > 0; ) {
00384 Coefficient_traits::const_reference A_ij_B = c_i.coefficient(Variable(j));
00385 if (A_ij_B != 0) {
00386
00387 add_mul_assign(les_eq[j], A_ij_B, u1_i);
00388 sub_mul_assign(les_eq[j], A_ij_B, u2_i);
00389
00390 add_mul_assign(les_eq[j + n], A_ij_B, u2_i);
00391 }
00392 }
00393 Coefficient_traits::const_reference b_B = c_i.inhomogeneous_term();
00394 if (b_B != 0)
00395
00396 add_mul_assign(le_out, b_B, u2_i);
00397 }
00398
00399 row_index = 0;
00400 for (Constraint_System::const_iterator i = cs_after.begin(),
00401 cs_after_end = cs_after.end();
00402 i != cs_after_end;
00403 ++i, ++row_index) {
00404 Variable u3_i(row_index);
00405 const Constraint& c_i = *i;
00406 for (dimension_type j = n; j-- > 0; ) {
00407 Coefficient_traits::const_reference
00408 A_ij_C = c_i.coefficient(Variable(j + n));
00409 if (A_ij_C != 0) {
00410
00411 sub_mul_assign(les_eq[j], A_ij_C, u3_i);
00412
00413 add_mul_assign(les_eq[j+n], A_ij_C, u3_i);
00414 }
00415 Coefficient_traits::const_reference
00416 Ap_ij_C = c_i.coefficient(Variable(j));
00417 if (Ap_ij_C != 0)
00418
00419 add_mul_assign(les_eq[j+n], Ap_ij_C, u3_i);
00420 }
00421 Coefficient_traits::const_reference b_C = c_i.inhomogeneous_term();
00422 if (b_C != 0)
00423
00424 add_mul_assign(le_out, b_C, u3_i);
00425 }
00426
00427
00428 for (dimension_type i = s + 2*r; i-- > 0; )
00429 cs_out.insert(Variable(i) >= 0);
00430
00431
00432
00433 for (dimension_type j = 0; j < 2*n; ++j)
00434 cs_out.insert(les_eq[j] == 0);
00435 }
00436
00437 void
00438 fill_constraint_system_PR_original(const Constraint_System& cs,
00439 Constraint_System& cs_out,
00440 Linear_Expression& le_out) {
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
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
00460 add_mul_assign(les_eq[j], Ap_ij, lambda1_i);
00461
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
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
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
00476 add_mul_assign(le_out, b, lambda2_i);
00477 }
00478
00479
00480 for (dimension_type i = 2*m; i-- > 0; )
00481 cs_out.insert(Variable(i) >= 0);
00482
00483
00484
00485 for (dimension_type j = 0; j < 3*n; ++j)
00486 cs_out.insert(les_eq[j] == 0);
00487 }
00488
00489 bool
00490 termination_test_MS(const Constraint_System& cs) {
00491 Constraint_System cs_mip;
00492 fill_constraint_systems_MS(cs, cs_mip, cs_mip);
00493
00494 MIP_Problem mip = MIP_Problem(cs_mip.space_dimension(), cs_mip);
00495 return mip.is_satisfiable();
00496 }
00497
00498 bool
00499 one_affine_ranking_function_MS(const Constraint_System& cs, Generator& mu) {
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; ) {
00512 Variable vi(i);
00513 add_mul_assign(le, fp.coefficient(vi), vi);
00514 }
00515 mu = point(le, fp.divisor());
00516 return true;
00517 }
00518
00519 void
00520 all_affine_ranking_functions_MS(const Constraint_System& cs,
00521 C_Polyhedron& mu_space) {
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;
00556
00557 Variable::set_output_function(p_default_output_function);
00558 #endif
00559
00560 mu_space.swap(ph1);
00561 }
00562
00563 void
00564 all_affine_quasi_ranking_functions_MS(const Constraint_System& cs,
00565 C_Polyhedron& decreasing_mu_space,
00566 C_Polyhedron& bounded_mu_space) {
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
00594 Variable::set_output_function(p_default_output_function);
00595 #endif
00596
00597 decreasing_mu_space.swap(ph1);
00598 bounded_mu_space.swap(ph2);
00599 }
00600
00601 bool
00602 termination_test_PR_original(const Constraint_System& cs) {
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
00609
00610 cs_mip.insert(le_ineq <= -1);
00611
00612 MIP_Problem mip(cs_mip.space_dimension(), cs_mip);
00613 return mip.is_satisfiable();
00614 }
00615
00616 bool
00617 termination_test_PR(const Constraint_System& cs_before,
00618 const Constraint_System& cs_after) {
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
00640
00641 cs_mip.insert(le_ineq <= -1);
00642
00643 MIP_Problem mip(cs_mip.space_dimension(), cs_mip);
00644 return mip.is_satisfiable();
00645 }
00646
00647 bool
00648 one_affine_ranking_function_PR(const Constraint_System& cs_before,
00649 const Constraint_System& cs_after,
00650 Generator& mu) {
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
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
00683 const dimension_type n = cs_before.space_dimension();
00684 Linear_Expression le;
00685
00686 le += 0*Variable(n);
00687
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);
00701 }
00702 }
00703
00704 mu = point(le);
00705 return true;
00706 }
00707
00708 bool
00709 one_affine_ranking_function_PR_original(const Constraint_System& cs,
00710 Generator& mu) {
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
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
00738 le += 0*Variable(n);
00739
00740
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 }
00755 }
00756 }
00757
00758 mu = point(le);
00759 return true;
00760 }
00761
00762 void
00763 all_affine_ranking_functions_PR(const Constraint_System& cs_before,
00764 const Constraint_System& cs_after,
00765 NNC_Polyhedron& mu_space) {
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
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
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
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
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 }
00848
00849 mu_space = NNC_Polyhedron(gs_out);
00850
00851 mu_space.add_space_dimensions_and_embed(1);
00852 }
00853 }
00854
00855 void
00856 all_affine_ranking_functions_PR_original(const Constraint_System& cs,
00857 NNC_Polyhedron& mu_space) {
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
00864
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
00876 Variables_Set lambda1(Variable(0), Variable(m-1));
00877 ph.remove_space_dimensions(lambda1);
00878
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
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
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
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 }
00934
00935 mu_space = NNC_Polyhedron(gs_out);
00936
00937 mu_space.add_space_dimensions_and_embed(1);
00938 }
00939 }
00940
00941 }
00942
00943 }
00944
00945 }