|
PPL
0.12.1
|
00001 /* Affine_Space class implementation. 00002 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 00003 Copyright (C) 2010-2012 BUGSENG srl (http://bugseng.com) 00004 00005 This file is part of the Parma Polyhedra Library (PPL). 00006 00007 The PPL is free software; you can redistribute it and/or modify it 00008 under the terms of the GNU General Public License as published by the 00009 Free Software Foundation; either version 3 of the License, or (at your 00010 option) any later version. 00011 00012 The PPL is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00015 for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software Foundation, 00019 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 00020 00021 For the most up-to-date information see the Parma Polyhedra Library 00022 site: http://bugseng.com/products/ppl/ . */ 00023 00024 #include "ppl-config.h" 00025 #include "Affine_Space.defs.hh" 00026 #include <iostream> 00027 00028 namespace PPL = Parma_Polyhedra_Library; 00029 00030 PPL::Affine_Space::Affine_Space(const Generator_System& gs) { 00031 dimension_type space_dim = gs.space_dimension(); 00032 // First find a point or closure point and convert it to a 00033 // grid point and add to the (initially empty) set of grid generators. 00034 Grid_Generator_System ggs(space_dim); 00035 Linear_Expression point_expr; 00036 PPL_DIRTY_TEMP_COEFFICIENT(point_divisor); 00037 for (Generator_System::const_iterator g = gs.begin(), 00038 gs_end = gs.end(); g != gs_end; ++g) { 00039 if (g->is_ray()) 00040 throw std::invalid_argument("Affine_Space::Affine_Space(gs):\n" 00041 "gs contains rays."); 00042 else if (g->is_point() || g->is_closure_point()) { 00043 for (dimension_type i = space_dim; i-- > 0; ) { 00044 const Variable v(i); 00045 point_expr += g->coefficient(v) * v; 00046 point_divisor = g->divisor(); 00047 } 00048 ggs.insert(grid_point(point_expr, point_divisor)); 00049 goto non_empty; 00050 } 00051 } 00052 // No (closure) point was found. 00053 Grid(EMPTY).m_swap(gr); 00054 return; 00055 00056 non_empty: 00057 // Add a grid line for each line. If the generator is a (closure) 00058 // point, the grid line must have the direction given by a line 00059 // that joins the grid point already inserted and the new point. 00060 PPL_DIRTY_TEMP_COEFFICIENT(coeff); 00061 PPL_DIRTY_TEMP_COEFFICIENT(g_divisor); 00062 for (Generator_System::const_iterator g = gs.begin(), 00063 gs_end = gs.end(); g != gs_end; ++g) { 00064 Linear_Expression e; 00065 if (g->is_point() || g->is_closure_point()) { 00066 g_divisor = g->divisor(); 00067 for (dimension_type i = space_dim; i-- > 0; ) { 00068 const Variable v(i); 00069 coeff = point_expr.coefficient(v) * g_divisor; 00070 coeff -= g->coefficient(v) * point_divisor; 00071 e += coeff * v; 00072 } 00073 if (e.all_homogeneous_terms_are_zero()) 00074 continue; 00075 } 00076 else 00077 for (dimension_type i = space_dim; i-- > 0; ) { 00078 const Variable v(i); 00079 e += g->coefficient(v) * v; 00080 } 00081 ggs.insert(grid_line(e)); 00082 } 00083 Grid(ggs).m_swap(gr); 00084 PPL_ASSERT(OK()); 00085 } 00086 00087 00088 PPL::Affine_Space& 00089 PPL::Affine_Space::operator=(const Affine_Space& y) { 00090 gr = y.gr; 00091 return *this; 00092 } 00093 00094 PPL::dimension_type 00095 PPL::Affine_Space::affine_dimension() const { 00096 return gr.affine_dimension(); 00097 } 00098 00099 const PPL::Congruence_System& 00100 PPL::Affine_Space::congruences() const { 00101 return gr.congruences(); 00102 } 00103 00104 const PPL::Congruence_System& 00105 PPL::Affine_Space::minimized_congruences() const { 00106 return gr.minimized_congruences(); 00107 } 00108 00109 PPL::Generator_System 00110 PPL::Affine_Space::generators() const { 00111 // FIXME: implement by filtering the grid generators. 00112 abort(); 00113 } 00114 00115 PPL::Generator_System 00116 PPL::Affine_Space::minimized_generators() const { 00117 // FIXME: implement by filtering the grid generators. 00118 abort(); 00119 } 00120 00121 PPL::Poly_Con_Relation 00122 PPL::Affine_Space::relation_with(const Congruence& cg) const { 00123 return gr.relation_with(cg); 00124 } 00125 00126 PPL::Poly_Gen_Relation 00127 PPL::Affine_Space::relation_with(const Generator& g) const { 00128 return gr.relation_with(g); 00129 } 00130 00131 PPL::Poly_Con_Relation 00132 PPL::Affine_Space::relation_with(const Constraint& c) const { 00133 return gr.relation_with(c); 00134 } 00135 00136 bool 00137 PPL::Affine_Space::is_empty() const { 00138 return gr.is_empty(); 00139 } 00140 00141 bool 00142 PPL::Affine_Space::is_universe() const { 00143 return gr.is_universe(); 00144 } 00145 00146 bool 00147 PPL::Affine_Space::is_bounded() const { 00148 return gr.is_bounded(); 00149 } 00150 00151 bool 00152 PPL::Affine_Space::is_discrete() const { 00153 return gr.is_discrete(); 00154 } 00155 00156 bool 00157 PPL::Affine_Space::is_topologically_closed() const { 00158 return true; 00159 } 00160 00161 bool 00162 PPL::Affine_Space::contains_integer_point() const { 00163 return gr.contains_integer_point(); 00164 } 00165 00166 bool 00167 PPL::Affine_Space::constrains(const Variable var) const { 00168 return gr.constrains(var); 00169 } 00170 00171 bool 00172 PPL::Affine_Space::OK(bool check_not_empty) const { 00173 return gr.OK(check_not_empty); 00174 } 00175 00176 void 00177 PPL::Affine_Space::add_constraints(const Constraint_System& cs) { 00178 gr.add_constraints(cs); 00179 } 00180 00181 void 00182 PPL::Affine_Space::add_generator(const Generator& /*g*/) { 00183 // FIXME: do we want this method? 00184 abort(); 00185 } 00186 00187 void 00188 PPL::Affine_Space::add_recycled_congruences(Congruence_System& /*cgs*/) { 00189 // FIXME: do we want this method? 00190 abort(); 00191 } 00192 00193 void 00194 PPL::Affine_Space::add_recycled_generators(Generator_System& /*gs*/) { 00195 // FIXME: do we want this method? 00196 abort(); 00197 } 00198 00199 void 00200 PPL::Affine_Space::add_generators(const Generator_System& /*gs*/) { 00201 // FIXME: do we want this method? 00202 abort(); 00203 } 00204 00205 void 00206 PPL::Affine_Space::refine_with_constraint(const Constraint& c) { 00207 gr.refine_with_constraint(c); 00208 } 00209 00210 void 00211 PPL::Affine_Space::refine_with_constraints(const Constraint_System& cs) { 00212 gr.refine_with_constraints(cs); 00213 } 00214 00215 void 00216 PPL::Affine_Space::unconstrain(const Variable var) { 00217 gr.unconstrain(var); 00218 } 00219 00220 void 00221 PPL::Affine_Space::unconstrain(const Variables_Set& vars) { 00222 gr.unconstrain(vars); 00223 } 00224 00225 void 00226 PPL::Affine_Space::intersection_assign(const Affine_Space& y) { 00227 gr.intersection_assign(y.gr); 00228 } 00229 00230 void 00231 PPL::Affine_Space::upper_bound_assign(const Affine_Space& y) { 00232 // FIXME: horrible kludge to filter congruences away. 00233 gr.upper_bound_assign(y.gr); 00234 Affine_Space a(gr.constraints()); 00235 m_swap(a); 00236 } 00237 00238 bool 00239 PPL::Affine_Space::upper_bound_assign_if_exact(const Affine_Space& y) { 00240 return gr.upper_bound_assign_if_exact(y.gr); 00241 } 00242 00243 void 00244 PPL::Affine_Space::difference_assign(const Affine_Space& y) { 00245 gr.difference_assign(y.gr); 00246 } 00247 00248 bool 00249 PPL::Affine_Space::simplify_using_context_assign(const Affine_Space& y) { 00250 return gr.simplify_using_context_assign(y.gr); 00251 } 00252 00253 void 00254 PPL::Affine_Space::affine_image(const Variable var, 00255 const Linear_Expression& expr, 00256 Coefficient_traits::const_reference 00257 denominator) { 00258 gr.affine_image(var, expr, denominator); 00259 } 00260 00261 void 00262 PPL::Affine_Space:: 00263 affine_preimage(const Variable var, 00264 const Linear_Expression& expr, 00265 Coefficient_traits::const_reference denominator) { 00266 gr.affine_preimage(var, expr, denominator); 00267 } 00268 00269 void 00270 PPL::Affine_Space:: 00271 generalized_affine_image(const Variable var, 00272 const Relation_Symbol relsym, 00273 const Linear_Expression& expr, 00274 Coefficient_traits::const_reference denominator) { 00275 gr.generalized_affine_image(var, relsym, expr, denominator); 00276 } 00277 00278 void 00279 PPL::Affine_Space:: 00280 generalized_affine_preimage(const Variable var, 00281 const Relation_Symbol relsym, 00282 const Linear_Expression& expr, 00283 Coefficient_traits::const_reference denominator) { 00284 gr.generalized_affine_preimage(var, relsym, expr, denominator); 00285 } 00286 00287 void 00288 PPL::Affine_Space:: 00289 generalized_affine_image(const Linear_Expression& lhs, 00290 const Relation_Symbol relsym, 00291 const Linear_Expression& rhs) { 00292 gr.generalized_affine_image(lhs, relsym, rhs); 00293 } 00294 00295 void 00296 PPL::Affine_Space:: 00297 generalized_affine_preimage(const Linear_Expression& lhs, 00298 const Relation_Symbol relsym, 00299 const Linear_Expression& rhs) { 00300 gr.generalized_affine_preimage(lhs, relsym, rhs); 00301 } 00302 00303 void 00304 PPL::Affine_Space:: 00305 bounded_affine_image(const Variable var, 00306 const Linear_Expression& lb_expr, 00307 const Linear_Expression& ub_expr, 00308 Coefficient_traits::const_reference denominator) { 00309 gr.bounded_affine_image(var, lb_expr, ub_expr, denominator); 00310 } 00311 00312 00313 void 00314 PPL::Affine_Space:: 00315 bounded_affine_preimage(const Variable var, 00316 const Linear_Expression& lb_expr, 00317 const Linear_Expression& ub_expr, 00318 Coefficient_traits::const_reference denominator) { 00319 gr.bounded_affine_preimage(var, lb_expr, ub_expr, denominator); 00320 } 00321 00322 void 00323 PPL::Affine_Space::time_elapse_assign(const Affine_Space& y) { 00324 gr.time_elapse_assign(y.gr); 00325 } 00326 00328 bool 00329 PPL::operator==(const Affine_Space& x, const Affine_Space& y) { 00330 return x.gr == y.gr; 00331 } 00332 00333 bool 00334 PPL::Affine_Space::contains(const Affine_Space& y) const { 00335 return gr.contains(y.gr); 00336 } 00337 00338 bool 00339 PPL::Affine_Space::is_disjoint_from(const Affine_Space& y) const { 00340 return gr.is_disjoint_from(y.gr); 00341 } 00342 00343 void 00344 PPL::Affine_Space::ascii_dump(std::ostream& s) const { 00345 gr.ascii_dump(s); 00346 } 00347 00348 PPL_OUTPUT_DEFINITIONS(Affine_Space) 00349 00350 bool 00351 PPL::Affine_Space::ascii_load(std::istream& s) { 00352 return gr.ascii_load(s); 00353 } 00354 00355 PPL::memory_size_type 00356 PPL::Affine_Space::external_memory_in_bytes() const { 00357 return gr.external_memory_in_bytes(); 00358 } 00359 00360 void 00361 PPL::Affine_Space::add_space_dimensions_and_embed(dimension_type m) { 00362 gr.add_space_dimensions_and_embed(m); 00363 } 00364 00365 void 00366 PPL::Affine_Space::add_space_dimensions_and_project(dimension_type m) { 00367 gr.add_space_dimensions_and_project(m); 00368 } 00369 00370 void 00371 PPL::Affine_Space::concatenate_assign(const Affine_Space& y) { 00372 gr.concatenate_assign(y.gr); 00373 } 00374 00375 void 00376 PPL::Affine_Space::remove_space_dimensions(const Variables_Set& vars) { 00377 gr.remove_space_dimensions(vars); 00378 } 00379 00380 void 00381 PPL::Affine_Space::remove_higher_space_dimensions(const dimension_type 00382 new_dimension) { 00383 gr.remove_higher_space_dimensions(new_dimension); 00384 } 00385 00386 void 00387 PPL::Affine_Space::expand_space_dimension(Variable var, dimension_type m) { 00388 gr.expand_space_dimension(var, m); 00389 } 00390 00391 void 00392 PPL::Affine_Space::fold_space_dimensions(const Variables_Set& to_be_folded, 00393 Variable var) { 00394 gr.fold_space_dimensions(to_be_folded, var); 00395 } 00396 00397 void 00398 PPL::Affine_Space::widening_assign(const Affine_Space& y, unsigned*) { 00399 Affine_Space& x = *this; 00400 00401 // Dimension-compatibility check. 00402 if (x.space_dimension() != y.space_dimension()) 00403 throw_dimension_incompatible("widening_assign(y)", "y", y); 00404 00405 // Assume `y' is contained in or equal to `x'. 00406 PPL_EXPECT_HEAVY(copy_contains(x, y)); 00407 } 00408 00409 void 00410 PPL::Affine_Space::limited_extrapolation_assign(const Affine_Space& y, 00411 const Constraint_System&, 00412 unsigned*) { 00413 Affine_Space& x = *this; 00414 00415 // Dimension-compatibility check. 00416 if (x.space_dimension() != y.space_dimension()) 00417 throw_dimension_incompatible("widening_assign(y)", "y", y); 00418 00419 // Assume `y' is contained in or equal to `x'. 00420 PPL_EXPECT_HEAVY(copy_contains(x, y)); 00421 } 00422 00424 std::ostream& 00425 PPL::IO_Operators::operator<<(std::ostream& s, const Affine_Space& gr) { 00426 s << gr; 00427 return s; 00428 } 00429 00430 void 00431 PPL::Affine_Space 00432 ::throw_dimension_incompatible(const char* method, 00433 const char* other_name, 00434 dimension_type other_dim) const { 00435 std::ostringstream s; 00436 s << "PPL::Affine_Space::" << method << ":\n" 00437 << "this->space_dimension() == " << space_dimension() << ", " 00438 << other_name << ".space_dimension() == " << other_dim << "."; 00439 throw std::invalid_argument(s.str()); 00440 } 00441 00442 void 00443 PPL::Affine_Space 00444 ::throw_dimension_incompatible(const char* method, 00445 const char* as_name, 00446 const Affine_Space& as) const { 00447 throw_dimension_incompatible(method, as_name, as.space_dimension()); 00448 } 00449