00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00027 #include <expression.h>
00028 #include <print_seq.h>
00029 #include <print_matrix.h>
00030
00031 extern const char *expr_names[];
00032
00033 bool expression_node::is(unsigned int __tp) const
00034 {
00035 bool _res = false;
00036
00037 if((__tp & ex_any) == 0 || (__tp & ex_any) == ex_any)
00038 {
00039 if(__tp & ex_convex)
00040 {
00041 if(sem.property_flags.c_info == c_convex)
00042 _res = true;
00043 }
00044 else if(__tp & ex_concave)
00045 {
00046 if(sem.property_flags.c_info == c_concave)
00047 _res = true;
00048 }
00049 else
00050 _res = true;
00051 }
00052 else
00053 {
00054 if(__tp & ex_bound)
00055 {
00056 if(operator_type == EXPRINFO_VARIABLE &&
00057 (f_bounds.inf() != -INFINITY || f_bounds.sup() != INFINITY))
00058 _res = true;
00059 }
00060 if(__tp & ex_linear)
00061 {
00062 if((sem.degree == 1 || sem.property_flags.c_info == c_linear) &&
00063 operator_type != EXPRINFO_VARIABLE)
00064 _res = true;
00065 }
00066 if(__tp & ex_quadratic)
00067 {
00068 if(sem.degree == 2 && !(__tp & ex_convex && __tp & ex_concave))
00069 {
00070 if(__tp & ex_convex)
00071 {
00072 if(sem.property_flags.c_info == c_convex)
00073 _res = true;
00074 }
00075 else if(__tp & ex_concave)
00076 {
00077 if(sem.property_flags.c_info == c_concave)
00078 _res = true;
00079 }
00080 else
00081 _res = true;
00082 }
00083 }
00084 if(__tp & ex_polynomial)
00085 {
00086 if(sem.degree > 2 && !(__tp & ex_convex && __tp & ex_concave))
00087 {
00088 if(__tp & ex_convex)
00089 {
00090 if(sem.property_flags.c_info == c_convex)
00091 _res = true;
00092 }
00093 else if(__tp & ex_concave)
00094 {
00095 if(sem.property_flags.c_info == c_concave)
00096 _res = true;
00097 }
00098 else
00099 _res = true;
00100 }
00101 }
00102 if(__tp & ex_other)
00103 {
00104 if(sem.degree == -1 && sem.property_flags.c_info != c_linear &&
00105 !(__tp & ex_convex && __tp & ex_concave))
00106 {
00107 if(__tp & ex_convex)
00108 {
00109 if(sem.property_flags.c_info == c_convex)
00110 _res = true;
00111 }
00112 else if(__tp & ex_concave)
00113 {
00114 if(sem.property_flags.c_info == c_concave)
00115 _res = true;
00116 }
00117 else
00118 _res = true;
00119 }
00120 }
00121 }
00122
00123 if(_res)
00124 {
00125 if(__tp & ex_equality && !(__tp & (ex_bothbound|ex_inequality)) &&
00126 !f_bounds.is_thin())
00127 _res = false;
00128 if(__tp & ex_inequality && !(__tp & ex_equality) && f_bounds.is_thin())
00129 _res = false;
00130 if(__tp & ex_leftbound && f_bounds.inf() == -INFINITY)
00131 _res = false;
00132 if(__tp & ex_rightbound && f_bounds.sup() == INFINITY)
00133 _res = false;
00134 }
00135 if(_res || __tp == ex_kj || __tp == ex_org)
00136 {
00137 _res = true;
00138 if(__tp & ex_kj && __tp & ex_org)
00139 __tp &= ~(ex_kj|ex_org);
00140 if(__tp & ex_kj && !sem.kj_flag())
00141 _res = false;
00142 if(__tp & ex_org && sem.kj_flag())
00143 _res = false;
00144 }
00145 if(_res)
00146 {
00147 if(__tp & ex_redundant && __tp & ex_notredundant)
00148 __tp &= ~(ex_redundant|ex_notredundant);
00149 if(__tp & ex_redundant && !sem.redundancy())
00150 _res = false;
00151 if(__tp & ex_notredundant && sem.redundancy())
00152 _res = false;
00153 }
00154 if(_res)
00155 {
00156 if(__tp & ex_active_lo && __tp & ex_inactive_lo)
00157 __tp &= ~(ex_active_lo|ex_inactive_lo);
00158 if(__tp & ex_active_hi && __tp & ex_inactive_hi)
00159 __tp &= ~(ex_active_hi|ex_inactive_hi);
00160 if(__tp & ex_active_lo && sem.inactive_lo())
00161 _res = false;
00162 if(__tp & ex_inactive_lo && !sem.inactive_lo())
00163 _res = false;
00164 if(__tp & ex_active_hi && sem.inactive_hi())
00165 _res = false;
00166 if(__tp & ex_inactive_hi && !sem.inactive_hi())
00167 _res = false;
00168 }
00169 if(_res)
00170 {
00171 if(__tp & ex_integer && !sem.integer_flag())
00172 _res = false;
00173 }
00174 if(_res && __tp & (ex_exists|ex_forall|ex_free|ex_stochastic))
00175 {
00176 switch(sem.type())
00177 {
00178 case v_exists:
00179 _res = __tp & ex_exists ? 1 : 0;
00180 break;
00181 case v_forall:
00182 _res = __tp & ex_forall ? 1 : 0;
00183 break;
00184 case v_free:
00185 _res = __tp & ex_free ? 1 : 0;
00186 break;
00187 case v_stochastic:
00188 _res = __tp & ex_stochastic ? 1 : 0;
00189 break;
00190 }
00191 }
00192 return _res;
00193 }
00194
00195 std::ostream& operator<< (std::ostream& o, const expression_node& __x)
00196 {
00197 int precsave = o.precision(18);
00198
00199 switch(__x.operator_type)
00200 {
00201 case EXPRINFO_QUAD:
00202 case EXPRINFO_LOOKUP:
00203 case EXPRINFO_PWLIN:
00204 case EXPRINFO_SPLINE:
00205 case EXPRINFO_PWCONSTLC:
00206 case EXPRINFO_PWCONSTRC:
00207 case EXPRINFO_CMPROD:
00208 case EXPRINFO_CGFEM:
00209 o << "<M> " << __x.node_num << " D R " << __x.params.m().nrows() << ' '
00210 << __x.params.m().ncols() << '\n';
00211 for(int i = 0; i < __x.params.m().nrows(); ++i)
00212 {
00213 const matrix<double>::Row &r(__x.params.m()[i]);
00214 if(r.nnz() == 0) continue;
00215 if(9*r.nnz() < 8*r.size())
00216 {
00217 o << "<r> " << __x.node_num << ' ' << i << ' ' << r.nz_struct() <<
00218 ": ";
00219 matrix<double>::Row::const_iterator _x(r.begin());
00220 o << *_x;
00221 for(++_x; _x != r.end(); ++_x)
00222 o << ',' << *_x;
00223 }
00224 else
00225 {
00226 o << "<R> " << __x.node_num << ' ' << i << ' ' << r[0];
00227 for(int j = 1; j < r.size(); ++j)
00228 o << ',' << r[j];
00229 }
00230 o << '\n';
00231 }
00232 break;
00233
00234 case EXPRINFO_LEVEL:
00235 o << "<M> " << __x.node_num << " I R " << __x.params.im().nrows() << ' '
00236 << __x.params.im().ncols() << '\n';
00237 for(int i = 0; i < __x.params.im().nrows(); ++i)
00238 {
00239 const matrix<interval>::Row &r(__x.params.im()[i]);
00240 if(r.nnz() == 0) continue;
00241 if(17*r.nnz() < 16*r.size())
00242 {
00243 o << "<r> " << __x.node_num << ' ' << i << ' ' << r.nz_struct() <<
00244 ": ";
00245 matrix<interval>::Row::const_iterator _x = r.begin();
00246 __wr_interval(o, *_x);
00247 for(++_x; _x != r.end(); ++_x)
00248 {
00249 o << ',';
00250 __wr_interval(o, *_x);
00251 }
00252 }
00253 else
00254 {
00255 o << "<R> " << __x.node_num << ' ' << i << ' ';
00256 __wr_interval(o, r[0]);
00257 for(int j = 1; j < r.size(); ++j)
00258 {
00259 o << ',';
00260 __wr_interval(o, r[j]);
00261 }
00262 }
00263 o << '\n';
00264 }
00265 break;
00266
00267 case EXPRINFO_DET:
00268 case EXPRINFO_COND:
00269 case EXPRINFO_PSD:
00270 case EXPRINFO_MPROD:
00271 case EXPRINFO_FEM:
00272 o << "<M> " << __x.node_num << " N R " << __x.params.nm().nrows() << ' '
00273 << __x.params.nm().ncols() << '\n';
00274 for(int i = 0; i < __x.params.nm().nrows(); ++i)
00275 {
00276 const matrix<int>::Row &r(__x.params.nm()[i]);
00277 if(r.nnz() == 0) continue;
00278 if(2*r.nnz() < r.size())
00279 {
00280 o << "<r> " << __x.node_num << ' ' << i << ' ' << r.nz_struct() <<
00281 ": ";
00282 matrix<int>::Row::const_iterator _x(r.begin());
00283 o << *_x;
00284 for(++_x; _x != r.end(); ++_x)
00285 o << ',' << *_x;
00286 }
00287 else
00288 {
00289 o << "<R> " << __x.node_num << ' ' << i << ' ' << r[0];
00290 for(int j = 1; j < r.size(); ++j)
00291 o << ',' << r[j];
00292 }
00293 o << '\n';
00294 }
00295 break;
00296 default:
00297
00298 break;
00299 }
00300
00301 o << "<" << __x.node_num << "> ";
00302
00303 o << "s " << __x.sem << ": ";
00304
00305 if(__x.f_bounds.inf() != -INFINITY || __x.f_bounds.sup() != INFINITY)
00306 {
00307 o << "b ";
00308 __wr_interval(o, __x.f_bounds);
00309 o << ": ";
00310 }
00311
00312 if(__x.is_var && __x.operator_type < EXPRINFO_VARIABLE)
00313 {
00314 int fs=0;
00315
00316 o << "v ";
00317 for(std::vector<unsigned int>::const_iterator i = __x.var_idx.begin();
00318 i != __x.var_idx.end(); i++)
00319 {
00320 if(fs)
00321 o << ',';
00322 o << *i;
00323 fs = 1;
00324 }
00325 o << ": ";
00326 }
00327
00328 switch(__x.operator_type)
00329 {
00330 case EXPRINFO_GHOST:
00331 o << "G " << (__x.params.nb() ? 'T' : 'F');
00332 break;
00333
00334 case EXPRINFO_CONSTANT:
00335 o << "C ";
00336 if(__x.params.is_allocated())
00337 {
00338 int f=0;
00339 const std::vector<double>& __xxvd = __x.params.d();
00340
00341 for(std::vector<double>::const_iterator __i = __xxvd.begin();
00342 __i != __xxvd.end(); ++__i)
00343 {
00344 if(f)
00345 o << ',';
00346 o << *__i << " ";
00347 f = 1;
00348 }
00349 }
00350 else
00351 o << __x.params.nd() << " ";
00352 break;
00353
00354 case EXPRINFO_VARIABLE:
00355 o << "V " << __x.params.nn();
00356 break;
00357
00358 case EXPRINFO_SUM:
00359 case EXPRINFO_PROD:
00360 case EXPRINFO_MAX:
00361 case EXPRINFO_MIN:
00362 case EXPRINFO_INVERT:
00363 case EXPRINFO_SQUARE:
00364 case EXPRINFO_SQROOT:
00365 case EXPRINFO_ABS:
00366 case EXPRINFO_POW:
00367 case EXPRINFO_EXP:
00368 case EXPRINFO_LOG:
00369 case EXPRINFO_SIN:
00370 case EXPRINFO_COS:
00371 case EXPRINFO_ALLDIFF:
00372 o << "d " << __x.params.nd() << ": ";
00373 break;
00374
00375 case EXPRINFO_MONOME:
00376 case EXPRINFO_NEIGHBOR:
00377 case EXPRINFO_NOGOOD:
00378 o << "n ";
00379 {
00380 int f=0;
00381 const std::vector<int>& __xxvd = __x.params.n();
00382
00383 for(std::vector<int>::const_iterator __i = __xxvd.begin();
00384 __i != __xxvd.end(); ++__i)
00385 {
00386 if(f)
00387 o << ',';
00388 o << *__i << " ";
00389 f = 1;
00390 }
00391 }
00392 break;
00393
00394 case EXPRINFO_POLY:
00395 o << "d ";
00396 {
00397 int f=0;
00398 const std::vector<double>& __xxvd = __x.params.d();
00399
00400 for(std::vector<double>::const_iterator __i = __xxvd.begin();
00401 __i != __xxvd.end(); ++__i)
00402 {
00403 if(f)
00404 o << ',';
00405 o << *__i << " ";
00406 f = 1;
00407 }
00408 }
00409 break;
00410
00411 case EXPRINFO_IN:
00412 case EXPRINFO_AND:
00413 case EXPRINFO_OR:
00414 case EXPRINFO_IMPLIES:
00415 case EXPRINFO_COUNT:
00416 case EXPRINFO_INTEGRAL:
00417 o << "i ";
00418 {
00419 int f=0;
00420 const std::vector<interval>& __xxvd = __x.params.i();
00421
00422 for(std::vector<interval>::const_iterator __i = __xxvd.begin();
00423 __i != __xxvd.end(); ++__i)
00424 {
00425 if(f)
00426 o << ',';
00427 __wr_interval(o,*__i);
00428 o << " ";
00429 f = 1;
00430 }
00431 }
00432 break;
00433
00434 case EXPRINFO_INTPOWER:
00435 case EXPRINFO_LIN:
00436 o << "n " << __x.params.nn() << ": ";
00437 break;
00438
00439 case EXPRINFO_ATAN2:
00440 case EXPRINFO_DIV:
00441 case EXPRINFO_MEAN:
00442 case EXPRINFO_EXPECTATION:
00443 case EXPRINFO_SCPROD:
00444 case EXPRINFO_NORM:
00445 case EXPRINFO_RE:
00446 case EXPRINFO_IM:
00447 case EXPRINFO_ARG:
00448 case EXPRINFO_CPLXCONJ:
00449 break;
00450
00451 case EXPRINFO_QUAD:
00452 case EXPRINFO_LOOKUP:
00453 case EXPRINFO_PWLIN:
00454 case EXPRINFO_SPLINE:
00455 case EXPRINFO_PWCONSTLC:
00456 case EXPRINFO_PWCONSTRC:
00457 case EXPRINFO_CMPROD:
00458 case EXPRINFO_CGFEM:
00459 case EXPRINFO_LEVEL:
00460 case EXPRINFO_DET:
00461 case EXPRINFO_COND:
00462 case EXPRINFO_PSD:
00463 case EXPRINFO_MPROD:
00464 case EXPRINFO_FEM:
00465 o << "m " << __x.node_num << ": ";
00466 break;
00467
00468 case EXPRINFO_IF:
00469 case EXPRINFO_NOT:
00470 o << "i ";
00471 __wr_interval(o, __x.params.ni());
00472 o << ": ";
00473 break;
00474
00475 case EXPRINFO_GAUSS:
00476 o << "d " << __x.params.d()[0] << "," <<
00477 __x.params.d()[1] << ": ";
00478 break;
00479
00480 default:
00481 std::cerr << "Warning: printing of general functions not yet implemented!\n";
00482 break;
00483 }
00484
00485 if(__x.operator_type < EXPRINFO_VARIABLE)
00486 o << expr_names[-__x.operator_type];
00487 else if(__x.operator_type > 0)
00488 o << "f(" << __x.operator_type << ')';
00489
00490 o << std::endl;
00491 o.precision(precsave);
00492 return o;
00493 }