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 "BHRZ03_Certificate.defs.hh"
00028
00029 #include "Polyhedron.defs.hh"
00030 #include "assert.hh"
00031 #include <iostream>
00032
00033 namespace PPL = Parma_Polyhedra_Library;
00034
00035 PPL::BHRZ03_Certificate::BHRZ03_Certificate(const Polyhedron& ph)
00036 : affine_dim(0), lin_space_dim(0), num_constraints(0), num_points(0),
00037 num_rays_null_coord(ph.space_dimension(), 0) {
00038
00039
00040
00041
00042
00043 ph.minimize();
00044
00045 PPL_ASSERT(!ph.marked_empty());
00046
00047
00048
00049
00050
00051
00052 const dimension_type space_dim = ph.space_dimension();
00053 affine_dim = space_dim;
00054 PPL_ASSERT(num_constraints == 0);
00055 const Constraint_System& cs = ph.minimized_constraints();
00056 for (Constraint_System::const_iterator i = cs.begin(),
00057 cs_end = cs.end(); i != cs_end; ++i) {
00058 ++num_constraints;
00059 if (i->is_equality())
00060 --affine_dim;
00061 }
00062
00063 PPL_ASSERT(lin_space_dim == 0);
00064 PPL_ASSERT(num_points == 0);
00065 const Generator_System& gs = ph.minimized_generators();
00066 for (Generator_System::const_iterator i = gs.begin(),
00067 gs_end = gs.end(); i != gs_end; ++i)
00068 switch (i->type()) {
00069 case Generator::POINT:
00070
00071 case Generator::CLOSURE_POINT:
00072 ++num_points;
00073 break;
00074 case Generator::RAY:
00075
00076
00077
00078 {
00079 const Generator& r = *i;
00080 dimension_type num_zeroes = 0;
00081 for (dimension_type j = space_dim; j-- > 0; )
00082 if (r.coefficient(Variable(j)) == 0)
00083 ++num_zeroes;
00084 ++num_rays_null_coord[num_zeroes];
00085 }
00086 break;
00087 case Generator::LINE:
00088
00089
00090 ++lin_space_dim;
00091 break;
00092 }
00093 PPL_ASSERT(OK());
00094
00095
00096
00097
00098
00099
00100
00101
00102 if (!ph.is_necessarily_closed())
00103 ph.minimize();
00104 }
00105
00106 int
00107 PPL::BHRZ03_Certificate::compare(const BHRZ03_Certificate& y) const {
00108 PPL_ASSERT(OK() && y.OK());
00109 if (affine_dim != y.affine_dim)
00110 return affine_dim > y.affine_dim ? 1 : -1;
00111 if (lin_space_dim != y.lin_space_dim)
00112 return lin_space_dim > y.lin_space_dim ? 1 : -1;
00113 if (num_constraints != y.num_constraints)
00114 return num_constraints > y.num_constraints ? 1 : -1;
00115 if (num_points != y.num_points)
00116 return num_points > y.num_points ? 1 : -1;
00117
00118 const dimension_type space_dim = num_rays_null_coord.size();
00119 PPL_ASSERT(num_rays_null_coord.size() == y.num_rays_null_coord.size());
00120
00121
00122 for (dimension_type i = 0; i < space_dim; i++)
00123 if (num_rays_null_coord[i] != y.num_rays_null_coord[i])
00124 return num_rays_null_coord[i] > y.num_rays_null_coord[i] ? 1 : -1;
00125
00126 return 0;
00127 }
00128
00129 int
00130 PPL::BHRZ03_Certificate::compare(const Polyhedron& ph) const {
00131 PPL_ASSERT(ph.space_dimension() == num_rays_null_coord.size());
00132
00133
00134
00135
00136
00137
00138 ph.minimize();
00139
00140
00141 PPL_ASSERT(!ph.marked_empty());
00142
00143
00144
00145
00146
00147
00148 const dimension_type space_dim = ph.space_dimension();
00149 dimension_type ph_affine_dim = space_dim;
00150 dimension_type ph_num_constraints = 0;
00151 const Constraint_System& cs = ph.minimized_constraints();
00152 for (Constraint_System::const_iterator i = cs.begin(),
00153 cs_end = cs.end(); i != cs_end; ++i) {
00154 ++ph_num_constraints;
00155 if (i->is_equality())
00156 --ph_affine_dim;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165 if (!ph.is_necessarily_closed())
00166 ph.minimize();
00167
00168
00169 if (ph_affine_dim > affine_dim)
00170 return 1;
00171
00172
00173 PPL_ASSERT(ph_affine_dim == affine_dim);
00174
00175
00176
00177
00178 dimension_type ph_lin_space_dim = 0;
00179 dimension_type ph_num_points = 0;
00180 const Generator_System& gs = ph.minimized_generators();
00181 for (Generator_System::const_iterator i = gs.begin(),
00182 gs_end = gs.end(); i != gs_end; ++i)
00183 switch (i->type()) {
00184 case Generator::POINT:
00185
00186 case Generator::CLOSURE_POINT:
00187 ++ph_num_points;
00188 break;
00189 case Generator::RAY:
00190 break;
00191 case Generator::LINE:
00192
00193
00194 ++ph_lin_space_dim;
00195 break;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 if (!ph.is_necessarily_closed())
00205 ph.minimize();
00206
00207
00208
00209 if (ph_lin_space_dim > lin_space_dim)
00210 return 1;
00211
00212
00213
00214 PPL_ASSERT(ph_lin_space_dim == lin_space_dim);
00215
00216
00217
00218
00219 if (ph_num_constraints != num_constraints)
00220 return ph_num_constraints < num_constraints ? 1 : -1;
00221
00222
00223
00224
00225 if (ph_num_points != num_points)
00226 return ph_num_points < num_points ? 1 : -1;
00227
00228
00229
00230 std::vector<dimension_type> ph_num_rays_null_coord(ph.space_dim, 0);
00231 for (Generator_System::const_iterator i = gs.begin(),
00232 gs_end = gs.end(); i != gs_end; ++i)
00233 if (i->is_ray()) {
00234 const Generator& r = *i;
00235 dimension_type num_zeroes = 0;
00236 for (dimension_type j = space_dim; j-- > 0; )
00237 if (r.coefficient(Variable(j)) == 0)
00238 ++num_zeroes;
00239 ++ph_num_rays_null_coord[num_zeroes];
00240 }
00241
00242
00243 for (dimension_type i = 0; i < space_dim; i++)
00244 if (ph_num_rays_null_coord[i] != num_rays_null_coord[i])
00245 return ph_num_rays_null_coord[i] < num_rays_null_coord[i] ? 1 : -1;
00246
00247
00248 return 0;
00249 }
00250
00251 bool
00252 PPL::BHRZ03_Certificate::OK() const {
00253 #ifndef NDEBUG
00254 using std::endl;
00255 using std::cerr;
00256 #endif
00257
00258
00259 const dimension_type space_dim = num_rays_null_coord.size();
00260
00261 if (affine_dim > space_dim) {
00262 #ifndef NDEBUG
00263 cerr << "In the BHRZ03 certificate about a non-empty polyhedron:"
00264 << endl
00265 << "the affine dimension is greater than the space dimension!"
00266 << endl;
00267 #endif
00268 return false;
00269 }
00270
00271 if (lin_space_dim > affine_dim) {
00272 #ifndef NDEBUG
00273 cerr << "In the BHRZ03 certificate about a non-empty polyhedron:"
00274 << endl
00275 << "the lineality space dimension is greater than "
00276 << "the affine dimension!"
00277 << endl;
00278 #endif
00279 return false;
00280 }
00281
00282 if (num_constraints < space_dim - affine_dim) {
00283 #ifndef NDEBUG
00284 cerr << "In the BHRZ03 certificate about a non-empty polyhedron:"
00285 << endl
00286 << "in a vector space of dimension `n',"
00287 << "any polyhedron of affine dimension `k'" << endl
00288 << "should have `n-k' non-redundant constraints at least."
00289 << endl
00290 << "Here space_dim = " << space_dim << ", "
00291 << "affine_dim = " << affine_dim << ", "
00292 << "but num_constraints = " << num_constraints << "!"
00293 << endl;
00294 #endif
00295 return false;
00296 }
00297
00298 if (num_points == 0) {
00299 #ifndef NDEBUG
00300 cerr << "In the BHRZ03 certificate about a non-empty polyhedron:"
00301 << endl
00302 << "the generator system has no points!"
00303 << endl;
00304 #endif
00305 return false;
00306 }
00307
00308 if (lin_space_dim == space_dim) {
00309
00310 if (num_constraints > 0) {
00311 #ifndef NDEBUG
00312 cerr << "In the BHRZ03 certificate about a non-empty polyhedron:"
00313 << endl
00314 << "a universe polyhedron has non-redundant constraints!"
00315 << endl;
00316 #endif
00317 return false;
00318 }
00319
00320 if (num_points != 1) {
00321 #ifndef NDEBUG
00322 cerr << "In the BHRZ03 certificate about a non-empty polyhedron:"
00323 << endl
00324 << "a universe polyhedron has more than one non-redundant point!"
00325 << endl;
00326 #endif
00327 return false;
00328 }
00329 }
00330
00331
00332 return true;
00333 }