00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <ppl-config.h>
00026
00027 #include "Polyhedron.defs.hh"
00028 #include "BHRZ03_Certificate.defs.hh"
00029 #include "Rational_Box.hh"
00030 #include "Scalar_Products.defs.hh"
00031 #include "assert.hh"
00032 #include <iostream>
00033 #include <stdexcept>
00034 #include <deque>
00035
00036 namespace PPL = Parma_Polyhedra_Library;
00037
00038 void
00039 PPL::Polyhedron
00040 ::select_CH78_constraints(const Polyhedron& y,
00041 Constraint_System& cs_selection) const {
00042
00043 PPL_ASSERT(topology() == y.topology()
00044 && topology() == cs_selection.topology()
00045 && space_dim == y.space_dim);
00046 PPL_ASSERT(!marked_empty()
00047 && !has_pending_constraints()
00048 && generators_are_up_to_date());
00049 PPL_ASSERT(!y.marked_empty()
00050 && !y.has_something_pending()
00051 && y.constraints_are_minimized());
00052
00053
00054
00055
00056
00057
00058 for (dimension_type i = 0, end = y.con_sys.num_rows(); i < end; ++i) {
00059 const Constraint& c = y.con_sys[i];
00060 if (gen_sys.satisfied_by_all_generators(c))
00061 cs_selection.insert(c);
00062 }
00063 }
00064
00065 void
00066 PPL::Polyhedron
00067 ::select_H79_constraints(const Polyhedron& y,
00068 Constraint_System& cs_selected,
00069 Constraint_System& cs_not_selected) const {
00070
00071
00072 PPL_ASSERT(topology() == y.topology()
00073 && topology() == cs_selected.topology()
00074 && topology() == cs_not_selected.topology());
00075 PPL_ASSERT(space_dim == y.space_dim);
00076 PPL_ASSERT(!marked_empty()
00077 && !has_pending_generators()
00078 && constraints_are_up_to_date());
00079 PPL_ASSERT(!y.marked_empty()
00080 && !y.has_something_pending()
00081 && y.constraints_are_minimized()
00082 && y.generators_are_up_to_date());
00083
00084
00085 if (!y.is_necessarily_closed()) {
00086
00087 y.strongly_minimize_constraints();
00088
00089 y.update_generators();
00090 }
00091
00092
00093 if (!y.sat_g_is_up_to_date())
00094 y.update_sat_g();
00095 Bit_Matrix tmp_sat_g = y.sat_g;
00096
00097
00098
00099
00100 const Constraint_System& y_cs = y.con_sys;
00101 dimension_type num_rows = y_cs.num_rows();
00102 for (dimension_type i = 0; i < num_rows; ++i)
00103 if (y_cs[i].is_tautological()) {
00104 --num_rows;
00105 std::swap(tmp_sat_g[i], tmp_sat_g[num_rows]);
00106 }
00107 tmp_sat_g.rows_erase_to_end(num_rows);
00108 tmp_sat_g.sort_rows();
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 Bit_Row buffer;
00129
00130
00131 for (dimension_type i = 0, end = con_sys.num_rows(); i < end; ++i) {
00132 const Constraint& ci = con_sys[i];
00133
00134
00135
00136 buffer.clear();
00137 for (dimension_type j = y.gen_sys.num_rows(); j-- > 0; ) {
00138 const int sp_sgn = Scalar_Products::sign(ci, y.gen_sys[j]);
00139
00140 PPL_ASSERT(sp_sgn >= 0
00141 || (!is_necessarily_closed()
00142 && ci.is_strict_inequality()
00143 && y.gen_sys[j].is_point()));
00144 if (sp_sgn > 0)
00145 buffer.set(j);
00146 }
00147
00148
00149 if (tmp_sat_g.sorted_contains(buffer))
00150 cs_selected.insert(ci);
00151 else
00152 cs_not_selected.insert(ci);
00153 }
00154 }
00155
00156 void
00157 PPL::Polyhedron::H79_widening_assign(const Polyhedron& y, unsigned* tp) {
00158 Polyhedron& x = *this;
00159
00160 const Topology topol = x.topology();
00161 if (topol != y.topology())
00162 throw_topology_incompatible("H79_widening_assign(y)", "y", y);
00163
00164 if (x.space_dim != y.space_dim)
00165 throw_dimension_incompatible("H79_widening_assign(y)", "y", y);
00166
00167 #ifndef NDEBUG
00168 {
00169
00170 const Polyhedron x_copy = x;
00171 const Polyhedron y_copy = y;
00172 PPL_ASSERT_HEAVY(x_copy.contains(y_copy));
00173 }
00174 #endif
00175
00176
00177
00178 if (x.space_dim == 0 || x.marked_empty() || y.marked_empty())
00179 return;
00180
00181
00182
00183 if (y.is_necessarily_closed()) {
00184 if (!y.minimize())
00185
00186 return;
00187 }
00188 else {
00189
00190
00191
00192
00193
00194
00195
00196 Polyhedron& yy = const_cast<Polyhedron&>(y);
00197 yy.intersection_assign(x);
00198 if (yy.is_empty())
00199
00200 return;
00201 }
00202
00203
00204
00205
00206
00207 if (x.has_pending_generators() || !x.constraints_are_up_to_date()) {
00208 Constraint_System CH78_cs(topol);
00209 x.select_CH78_constraints(y, CH78_cs);
00210
00211 if (CH78_cs.num_rows() == y.con_sys.num_rows()) {
00212
00213 x = y;
00214 return;
00215 }
00216
00217
00218
00219 else if (CH78_cs.num_equalities() == y.con_sys.num_equalities()) {
00220
00221 Polyhedron CH78(topol, x.space_dim, UNIVERSE);
00222 CH78.add_recycled_constraints(CH78_cs);
00223
00224
00225
00226 if (tp != 0 && *tp > 0) {
00227
00228
00229 if (!x.contains(CH78))
00230 --(*tp);
00231 }
00232 else
00233
00234 std::swap(x, CH78);
00235 PPL_ASSERT_HEAVY(x.OK(true));
00236 return;
00237 }
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 if (has_pending_generators())
00250 process_pending_generators();
00251 else if (!x.constraints_are_up_to_date())
00252 x.update_constraints();
00253
00254
00255
00256 Constraint_System H79_cs(topol);
00257 Constraint_System x_minus_H79_cs(topol);
00258 x.select_H79_constraints(y, H79_cs, x_minus_H79_cs);
00259
00260 if (x_minus_H79_cs.has_no_rows())
00261
00262
00263 return;
00264 else {
00265
00266
00267
00268
00269 Polyhedron H79(topol, x.space_dim, UNIVERSE);
00270 H79.add_recycled_constraints(H79_cs);
00271
00272
00273
00274 if (tp != 0 && *tp > 0) {
00275
00276
00277 if (!x.contains(H79))
00278 --(*tp);
00279 }
00280 else
00281
00282 std::swap(x, H79);
00283 PPL_ASSERT_HEAVY(x.OK(true));
00284 }
00285 }
00286
00287 void
00288 PPL::Polyhedron::limited_H79_extrapolation_assign(const Polyhedron& y,
00289 const Constraint_System& cs,
00290 unsigned* tp) {
00291 Polyhedron& x = *this;
00292
00293 const dimension_type cs_num_rows = cs.num_rows();
00294
00295 if (cs_num_rows == 0) {
00296 x.H79_widening_assign(y, tp);
00297 return;
00298 }
00299
00300
00301 if (x.is_necessarily_closed()) {
00302 if (!y.is_necessarily_closed())
00303 throw_topology_incompatible("limited_H79_extrapolation_assign(y, cs)",
00304 "y", y);
00305 if (cs.has_strict_inequalities())
00306 throw_topology_incompatible("limited_H79_extrapolation_assign(y, cs)",
00307 "cs", cs);
00308 }
00309 else if (y.is_necessarily_closed())
00310 throw_topology_incompatible("limited_H79_extrapolation_assign(y, cs)",
00311 "y", y);
00312
00313
00314 if (x.space_dim != y.space_dim)
00315 throw_dimension_incompatible("limited_H79_extrapolation_assign(y, cs)",
00316 "y", y);
00317
00318 const dimension_type cs_space_dim = cs.space_dimension();
00319 if (x.space_dim < cs_space_dim)
00320 throw_dimension_incompatible("limited_H79_extrapolation_assign(y, cs)",
00321 "cs", cs);
00322
00323 #ifndef NDEBUG
00324 {
00325
00326 const Polyhedron x_copy = x;
00327 const Polyhedron y_copy = y;
00328 PPL_ASSERT_HEAVY(x_copy.contains(y_copy));
00329 }
00330 #endif
00331
00332 if (y.marked_empty())
00333 return;
00334 if (x.marked_empty())
00335 return;
00336
00337
00338
00339
00340 if (x.space_dim == 0)
00341 return;
00342
00343 if (!y.minimize())
00344
00345 return;
00346
00347
00348
00349
00350 if ((x.has_pending_constraints() && !x.process_pending_constraints())
00351 || (!x.generators_are_up_to_date() && !x.update_generators()))
00352
00353 return;
00354
00355 Constraint_System new_cs;
00356
00357
00358 const Generator_System& x_gen_sys = x.gen_sys;
00359
00360
00361 for (dimension_type i = 0; i < cs_num_rows; ++i) {
00362 const Constraint& c = cs[i];
00363 if (x_gen_sys.satisfied_by_all_generators(c))
00364 new_cs.insert(c);
00365 }
00366 x.H79_widening_assign(y, tp);
00367 x.add_recycled_constraints(new_cs);
00368 PPL_ASSERT_HEAVY(OK());
00369 }
00370
00371 void
00372 PPL::Polyhedron::bounded_H79_extrapolation_assign(const Polyhedron& y,
00373 const Constraint_System& cs,
00374 unsigned* tp) {
00375 Rational_Box x_box(*this, ANY_COMPLEXITY);
00376 Rational_Box y_box(y, ANY_COMPLEXITY);
00377 x_box.CC76_widening_assign(y_box);
00378 limited_H79_extrapolation_assign(y, cs, tp);
00379 Constraint_System x_box_cs = x_box.constraints();
00380 add_recycled_constraints(x_box_cs);
00381 }
00382
00383 bool
00384 PPL::Polyhedron
00385 ::BHRZ03_combining_constraints(const Polyhedron& y,
00386 const BHRZ03_Certificate& y_cert,
00387 const Polyhedron& H79,
00388 const Constraint_System& x_minus_H79_cs) {
00389 Polyhedron& x = *this;
00390
00391 PPL_ASSERT(x.topology() == y.topology()
00392 && x.topology() == H79.topology()
00393 && x.topology() == x_minus_H79_cs.topology());
00394 PPL_ASSERT(x.space_dim == y.space_dim
00395 && x.space_dim == H79.space_dim
00396 && x.space_dim == x_minus_H79_cs.space_dimension());
00397 PPL_ASSERT(!x.marked_empty() && !x.has_something_pending()
00398 && x.constraints_are_minimized() && x.generators_are_minimized());
00399 PPL_ASSERT(!y.marked_empty() && !y.has_something_pending()
00400 && y.constraints_are_minimized() && y.generators_are_minimized());
00401 PPL_ASSERT(!H79.marked_empty() && !H79.has_something_pending()
00402 && H79.constraints_are_minimized() && H79.generators_are_minimized());
00403
00404
00405
00406
00407
00408
00409
00410
00411 const dimension_type x_minus_H79_cs_num_rows = x_minus_H79_cs.num_rows();
00412 if (x_minus_H79_cs_num_rows <= 1)
00413 return false;
00414
00415 const Topology topol = x.topology();
00416 Constraint_System combining_cs(topol);
00417 Constraint_System new_cs(topol);
00418
00419
00420
00421 const bool closed = x.is_necessarily_closed();
00422 for (dimension_type i = y.gen_sys.num_rows(); i-- > 0; ) {
00423 const Generator& g = y.gen_sys[i];
00424 if ((g.is_point() && closed) || (g.is_closure_point() && !closed)) {
00425
00426
00427
00428 bool lies_on_the_boundary_of_H79 = false;
00429 const Constraint_System& H79_cs = H79.con_sys;
00430 for (dimension_type j = H79_cs.num_rows(); j-- > 0; ) {
00431 const Constraint& c = H79_cs[j];
00432 if (c.is_inequality() && Scalar_Products::sign(c, g) == 0) {
00433 lies_on_the_boundary_of_H79 = true;
00434 break;
00435 }
00436 }
00437 if (lies_on_the_boundary_of_H79)
00438 continue;
00439
00440
00441
00442 combining_cs.clear();
00443 for (dimension_type j = x_minus_H79_cs_num_rows; j-- > 0; ) {
00444 const Constraint& c = x_minus_H79_cs[j];
00445 if (Scalar_Products::sign(c, g) == 0)
00446 combining_cs.insert(c);
00447 }
00448
00449 const dimension_type combining_cs_num_rows = combining_cs.num_rows();
00450 if (combining_cs_num_rows > 0) {
00451 if (combining_cs_num_rows == 1)
00452
00453 new_cs.insert(combining_cs[0]);
00454 else {
00455 Linear_Expression e(0);
00456 bool strict_inequality = false;
00457 for (dimension_type h = combining_cs_num_rows; h-- > 0; ) {
00458 if (combining_cs[h].is_strict_inequality())
00459 strict_inequality = true;
00460 e += Linear_Expression(combining_cs[h]);
00461 }
00462
00463 if (!e.all_homogeneous_terms_are_zero()) {
00464 if (strict_inequality)
00465 new_cs.insert(e > 0);
00466 else
00467 new_cs.insert(e >= 0);
00468 }
00469 }
00470 }
00471 }
00472 }
00473
00474
00475
00476 bool improves_upon_H79 = false;
00477 const Poly_Con_Relation si = Poly_Con_Relation::strictly_intersects();
00478 for (dimension_type i = new_cs.num_rows(); i-- > 0; )
00479 if (H79.relation_with(new_cs[i]) == si) {
00480 improves_upon_H79 = true;
00481 break;
00482 }
00483 if (!improves_upon_H79)
00484 return false;
00485
00486
00487
00488 Polyhedron result = H79;
00489 result.add_recycled_constraints(new_cs);
00490
00491 result.minimize();
00492
00493
00494
00495 if (y_cert.is_stabilizing(result) && !result.contains(H79)) {
00496
00497 std::swap(x, result);
00498 PPL_ASSERT_HEAVY(x.OK(true));
00499 return true;
00500 }
00501 else
00502
00503 return false;
00504 }
00505
00506 bool
00507 PPL::Polyhedron::BHRZ03_evolving_points(const Polyhedron& y,
00508 const BHRZ03_Certificate& y_cert,
00509 const Polyhedron& H79) {
00510 Polyhedron& x = *this;
00511
00512 PPL_ASSERT(x.topology() == y.topology()
00513 && x.topology() == H79.topology());
00514 PPL_ASSERT(x.space_dim == y.space_dim
00515 && x.space_dim == H79.space_dim);
00516 PPL_ASSERT(!x.marked_empty() && !x.has_something_pending()
00517 && x.constraints_are_minimized() && x.generators_are_minimized());
00518 PPL_ASSERT(!y.marked_empty() && !y.has_something_pending()
00519 && y.constraints_are_minimized() && y.generators_are_minimized());
00520 PPL_ASSERT(!H79.marked_empty() && !H79.has_something_pending()
00521 && H79.constraints_are_minimized() && H79.generators_are_minimized());
00522
00523
00524
00525
00526
00527 Generator_System candidate_rays;
00528
00529 const dimension_type x_gen_sys_num_rows = x.gen_sys.num_rows();
00530 const dimension_type y_gen_sys_num_rows = y.gen_sys.num_rows();
00531 const bool closed = x.is_necessarily_closed();
00532 for (dimension_type i = x_gen_sys_num_rows; i-- > 0; ) {
00533 Generator& g1 = x.gen_sys[i];
00534
00535
00536
00537
00538 if (((g1.is_point() && closed) || (g1.is_closure_point() && !closed))
00539 && y.relation_with(g1) == Poly_Gen_Relation::nothing()) {
00540
00541
00542
00543 for (dimension_type j = y_gen_sys_num_rows; j-- > 0; ) {
00544 const Generator& g2 = y.gen_sys[j];
00545 if ((g2.is_point() && closed)
00546 || (g2.is_closure_point() && !closed)) {
00547 PPL_ASSERT(compare(g1, g2) != 0);
00548 Generator ray_from_g2_to_g1 = g1;
00549 ray_from_g2_to_g1.linear_combine(g2, 0);
00550 candidate_rays.insert(ray_from_g2_to_g1);
00551 }
00552 }
00553 }
00554 }
00555
00556
00557 Polyhedron result = x;
00558 result.add_recycled_generators(candidate_rays);
00559 result.intersection_assign(H79);
00560
00561 result.minimize();
00562
00563
00564
00565 if (y_cert.is_stabilizing(result) && !result.contains(H79)) {
00566
00567 std::swap(x, result);
00568 PPL_ASSERT_HEAVY(x.OK(true));
00569 return true;
00570 }
00571 else
00572
00573 return false;
00574 }
00575
00576 bool
00577 PPL::Polyhedron::BHRZ03_evolving_rays(const Polyhedron& y,
00578 const BHRZ03_Certificate& y_cert,
00579 const Polyhedron& H79) {
00580 Polyhedron& x = *this;
00581
00582 PPL_ASSERT(x.topology() == y.topology()
00583 && x.topology() == H79.topology());
00584 PPL_ASSERT(x.space_dim == y.space_dim
00585 && x.space_dim == H79.space_dim);
00586 PPL_ASSERT(!x.marked_empty() && !x.has_something_pending()
00587 && x.constraints_are_minimized() && x.generators_are_minimized());
00588 PPL_ASSERT(!y.marked_empty() && !y.has_something_pending()
00589 && y.constraints_are_minimized() && y.generators_are_minimized());
00590 PPL_ASSERT(!H79.marked_empty() && !H79.has_something_pending()
00591 && H79.constraints_are_minimized() && H79.generators_are_minimized());
00592
00593 const dimension_type x_gen_sys_num_rows = x.gen_sys.num_rows();
00594 const dimension_type y_gen_sys_num_rows = y.gen_sys.num_rows();
00595
00596
00597 Generator_System candidate_rays;
00598 PPL_DIRTY_TEMP_COEFFICIENT(tmp);
00599 for (dimension_type i = x_gen_sys_num_rows; i-- > 0; ) {
00600 const Generator& x_g = x.gen_sys[i];
00601
00602 if (x_g.is_ray() && y.relation_with(x_g) == Poly_Gen_Relation::nothing()) {
00603 for (dimension_type j = y_gen_sys_num_rows; j-- > 0; ) {
00604 const Generator& y_g = y.gen_sys[j];
00605 if (y_g.is_ray()) {
00606 Generator new_ray(x_g);
00607
00608
00609 std::deque<bool> considered(x.space_dim + 1);
00610 for (dimension_type k = 1; k < x.space_dim; ++k)
00611 if (!considered[k])
00612 for (dimension_type h = k + 1; h <= x.space_dim; ++h)
00613 if (!considered[h]) {
00614 tmp = x_g[k] * y_g[h];
00615
00616
00617 sub_mul_assign(tmp, x_g[h], y_g[k]);
00618 const int clockwise
00619 = sgn(tmp);
00620 const int first_or_third_quadrant
00621 = sgn(x_g[k]) * sgn(x_g[h]);
00622 switch (clockwise * first_or_third_quadrant) {
00623 case -1:
00624 new_ray[k] = 0;
00625 considered[k] = true;
00626 break;
00627 case 1:
00628 new_ray[h] = 0;
00629 considered[h] = true;
00630 break;
00631 default:
00632 break;
00633 }
00634 }
00635 new_ray.normalize();
00636 candidate_rays.insert(new_ray);
00637 }
00638 }
00639 }
00640 }
00641
00642
00643 if (candidate_rays.has_no_rows())
00644 return false;
00645
00646
00647 Polyhedron result = x;
00648 result.add_recycled_generators(candidate_rays);
00649 result.intersection_assign(H79);
00650
00651 result.minimize();
00652
00653
00654 if (y_cert.is_stabilizing(result) && !result.contains(H79)) {
00655
00656 std::swap(x, result);
00657 PPL_ASSERT_HEAVY(x.OK(true));
00658 return true;
00659 }
00660 else
00661
00662 return false;
00663 }
00664
00665 void
00666 PPL::Polyhedron::BHRZ03_widening_assign(const Polyhedron& y, unsigned* tp) {
00667 Polyhedron& x = *this;
00668
00669 if (x.topology() != y.topology())
00670 throw_topology_incompatible("BHRZ03_widening_assign(y)", "y", y);
00671
00672 if (x.space_dim != y.space_dim)
00673 throw_dimension_incompatible("BHRZ03_widening_assign(y)", "y", y);
00674
00675 #ifndef NDEBUG
00676 {
00677
00678 const Polyhedron x_copy = x;
00679 const Polyhedron y_copy = y;
00680 PPL_ASSERT_HEAVY(x_copy.contains(y_copy));
00681 }
00682 #endif
00683
00684
00685
00686 if (x.space_dim == 0 || x.marked_empty() || y.marked_empty())
00687 return;
00688
00689
00690 if (!y.minimize())
00691
00692 return;
00693
00694 x.minimize();
00695
00696
00697 BHRZ03_Certificate y_cert(y);
00698
00699
00700
00701
00702 if (y_cert.is_stabilizing(x) || y.contains(x)) {
00703 PPL_ASSERT_HEAVY(OK());
00704 return;
00705 }
00706
00707
00708
00709
00710 if (tp != 0 && *tp > 0) {
00711 --(*tp);
00712 PPL_ASSERT_HEAVY(OK());
00713 return;
00714 }
00715
00716
00717
00718
00719 const Topology topol = x.topology();
00720 Constraint_System H79_cs(topol);
00721 Constraint_System x_minus_H79_cs(topol);
00722 x.select_H79_constraints(y, H79_cs, x_minus_H79_cs);
00723
00724
00725
00726 PPL_ASSERT(!x_minus_H79_cs.has_no_rows());
00727
00728
00729 Polyhedron H79(topol, x.space_dim, UNIVERSE);
00730 H79.add_recycled_constraints(H79_cs);
00731
00732 H79.minimize();
00733
00734
00735
00736 if (x.BHRZ03_combining_constraints(y, y_cert, H79, x_minus_H79_cs))
00737 return;
00738
00739 PPL_ASSERT_HEAVY(H79.OK() && x.OK() && y.OK());
00740
00741 if (x.BHRZ03_evolving_points(y, y_cert, H79))
00742 return;
00743
00744 PPL_ASSERT_HEAVY(H79.OK() && x.OK() && y.OK());
00745
00746 if (x.BHRZ03_evolving_rays(y, y_cert, H79))
00747 return;
00748
00749 PPL_ASSERT_HEAVY(H79.OK() && x.OK() && y.OK());
00750
00751
00752 std::swap(x, H79);
00753 PPL_ASSERT_HEAVY(x.OK(true));
00754
00755 #ifndef NDEBUG
00756
00757 PPL_ASSERT(y_cert.is_stabilizing(x));
00758 #endif
00759 }
00760
00761 void
00762 PPL::Polyhedron
00763 ::limited_BHRZ03_extrapolation_assign(const Polyhedron& y,
00764 const Constraint_System& cs,
00765 unsigned* tp) {
00766 Polyhedron& x = *this;
00767 const dimension_type cs_num_rows = cs.num_rows();
00768
00769 if (cs_num_rows == 0) {
00770 x.BHRZ03_widening_assign(y, tp);
00771 return;
00772 }
00773
00774
00775 if (x.is_necessarily_closed()) {
00776 if (!y.is_necessarily_closed())
00777 throw_topology_incompatible("limited_BHRZ03_extrapolation_assign(y, cs)",
00778 "y", y);
00779 if (cs.has_strict_inequalities())
00780 throw_topology_incompatible("limited_BHRZ03_extrapolation_assign(y, cs)",
00781 "cs", cs);
00782 }
00783 else if (y.is_necessarily_closed())
00784 throw_topology_incompatible("limited_BHRZ03_extrapolation_assign(y, cs)",
00785 "y", y);
00786
00787
00788 if (x.space_dim != y.space_dim)
00789 throw_dimension_incompatible("limited_BHRZ03_extrapolation_assign(y, cs)",
00790 "y", y);
00791
00792 const dimension_type cs_space_dim = cs.space_dimension();
00793 if (x.space_dim < cs_space_dim)
00794 throw_dimension_incompatible("limited_BHRZ03_extrapolation_assign(y, cs)",
00795 "cs", cs);
00796
00797 #ifndef NDEBUG
00798 {
00799
00800 const Polyhedron x_copy = x;
00801 const Polyhedron y_copy = y;
00802 PPL_ASSERT_HEAVY(x_copy.contains(y_copy));
00803 }
00804 #endif
00805
00806 if (y.marked_empty())
00807 return;
00808 if (x.marked_empty())
00809 return;
00810
00811
00812
00813
00814 if (x.space_dim == 0)
00815 return;
00816
00817 if (!y.minimize())
00818
00819 return;
00820
00821
00822
00823
00824 if ((x.has_pending_constraints() && !x.process_pending_constraints())
00825 || (!x.generators_are_up_to_date() && !x.update_generators()))
00826
00827 return;
00828
00829 Constraint_System new_cs;
00830
00831
00832 const Generator_System& x_gen_sys = x.gen_sys;
00833
00834
00835 for (dimension_type i = 0; i < cs_num_rows; ++i) {
00836 const Constraint& c = cs[i];
00837 if (x_gen_sys.satisfied_by_all_generators(c))
00838 new_cs.insert(c);
00839 }
00840 x.BHRZ03_widening_assign(y, tp);
00841 x.add_recycled_constraints(new_cs);
00842 PPL_ASSERT_HEAVY(OK());
00843 }
00844
00845 void
00846 PPL::Polyhedron
00847 ::bounded_BHRZ03_extrapolation_assign(const Polyhedron& y,
00848 const Constraint_System& cs,
00849 unsigned* tp) {
00850 Rational_Box x_box(*this, ANY_COMPLEXITY);
00851 Rational_Box y_box(y, ANY_COMPLEXITY);
00852 x_box.CC76_widening_assign(y_box);
00853 limited_BHRZ03_extrapolation_assign(y, cs, tp);
00854 Constraint_System x_box_cs = x_box.constraints();
00855 add_recycled_constraints(x_box_cs);
00856 }