00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CouenneExpression.hpp"
00012 #include "CouenneExprAux.hpp"
00013 #include "CouenneExprClone.hpp"
00014 #include "CouenneExprOp.hpp"
00015 #include "CouenneExprGroup.hpp"
00016 #include "CouenneExprQuad.hpp"
00017 #include "CouenneExprConst.hpp"
00018 #include "CouennePrecisions.hpp"
00019
00020 #include <cstdio>
00021
00022 using namespace Couenne;
00023
00024 namespace Couenne {
00025 class CouenneProblem;
00026 class Domain;
00027 }
00028
00029
00030 exprOp::~exprOp () {
00031
00032 if (arglist_) {
00033 for (expression **alist = arglist_; nargs_--; alist++)
00034 if (*alist) delete (*alist);
00035 delete [] arglist_;
00036 }
00037 }
00038
00039
00040
00041
00042 void exprOp::print (std::ostream &out,
00043 bool descend) const {
00044
00045 if (printPos () == PRE)
00046 out << printOp ();
00047
00048 if (nargs_ > 1)
00049 {out << "("; fflush (stdout);}
00050 for (int i=0; i<nargs_; i++) {
00051 if (arglist_ [i])
00052 arglist_ [i] -> print (out, descend);
00053 fflush (stdout);
00054 if (i < nargs_ - 1) {
00055 if (printPos () == INSIDE) out << printOp ();
00056 else out << ",";
00057 }
00058 if (!((i + 1) % MAX_ARG_LINE))
00059 out << std::endl;
00060 fflush (stdout);
00061 }
00062 if (nargs_ > 1) {
00063 out << ")";
00064 fflush (stdout);
00065 }
00066 }
00067
00068
00070
00071 int exprOp::compare (exprOp &e1) {
00072
00073 int c0 = code (),
00074 c1 = e1. code ();
00075
00076 if (c0 < c1) return -1;
00077 if (c0 > c1) return 1;
00078
00079
00080 if (nargs_ < e1.nargs_) return -1;
00081 if (nargs_ > e1.nargs_) return 1;
00082
00083
00084 for (register int i = nargs_; i--;) {
00085
00086 int res = arglist_ [i] -> compare (*(e1. ArgList () [i]));
00087 if (res) return res;
00088 }
00089
00090
00091 if ((c0 == COU_EXPRGROUP) ||
00092 (c0 == COU_EXPRQUAD)) {
00093
00094 exprGroup *ne0 = dynamic_cast <exprGroup *> (this),
00095 *ne1 = dynamic_cast <exprGroup *> (&e1);
00096
00097 int cg = ne0 -> compare (*ne1);
00098
00099 if (cg) return cg;
00100
00101
00102
00103 if (c0 == COU_EXPRQUAD) {
00104
00105 exprQuad *ne0 = dynamic_cast <exprQuad *> (this),
00106 *ne1 = dynamic_cast <exprQuad *> (&e1);
00107
00108 return ne0 -> compare (*ne1);
00109 }
00110 }
00111
00112 return 0;
00113 }
00114
00115
00117
00118 int exprOp::rank () {
00119
00120 int maxrank = -1;
00121
00122 for (expression **al = arglist_ + nargs_;
00123 al-- > arglist_;) {
00124 int r = (*al) -> rank ();
00125 if (r > maxrank) maxrank = r;
00126 }
00127
00128 return (maxrank);
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 exprAux *exprOp::standardize (CouenneProblem *p, bool addAux) {
00143
00144 exprVar *subst;
00145
00146 for (int i = 0; i < nargs_; ++i)
00147 if ((subst = arglist_ [i] -> standardize (p))) {
00148
00149 if ((subst -> Type () == VAR) ||
00150 (subst -> Type () == AUX))
00151 arglist_ [i] = new exprClone (subst);
00152 else arglist_ [i] = subst;
00153 }
00154 return NULL;
00155 }
00156
00157
00159 void exprOp::replace (exprVar *x, exprVar *w) {
00160
00161 expression **al = arglist_;
00162 int index = x -> Index ();
00163
00164 for (register int i = nargs_; i--; al++)
00165
00166 switch ((*al) -> Type ()) {
00167
00168 case AUX:
00169 case VAR:
00170 if ((*al) -> Index () == index) {
00171 delete *al;
00172 *al = new exprClone (w);
00173 }
00174 break;
00175
00176 case UNARY:
00177 case N_ARY:
00178 (*al) -> replace (x, w);
00179 break;
00180
00181 default:
00182 break;
00183 }
00184 }
00185
00186
00188 bool exprOp::isInteger () {
00189
00190 for (int i = nargs_; i--;)
00191
00192 if (!(arglist_ [i] -> isInteger ())) {
00193
00194
00195
00196 CouNumber lb, ub;
00197 arglist_ [i] -> getBounds (lb, ub);
00198
00199 if ((fabs (lb - ub) > COUENNE_EPS) ||
00200 !::isInteger (lb))
00201 return false;
00202 }
00203
00204 return true;
00205 }
00206
00207
00210 int exprOp::DepList (std::set <int> &deplist,
00211 enum dig_type type) {
00212 int tot = 0;
00213
00214
00215
00216 for (int i = nargs_; i--;) {
00217
00218
00219
00220
00221
00222
00223
00224 tot += arglist_ [i] -> DepList (deplist, type);
00225
00226
00227
00228
00229 }
00230
00231 return tot;
00232 }
00233
00235 void exprOp::realign (const CouenneProblem *p) {
00236
00237 for (int i=0; i<nargs_; i++)
00238 arglist_ [i] -> realign (p);
00239 }
00240
00241
00242
00243 expression *exprOp:: simplify () {
00244
00245
00246 for (int i=0; i<nargs_; i++) {
00247
00248 expression *subst;
00249
00250 if ((subst = arglist_ [i] -> simplify ())) {
00251
00252 delete arglist_ [i];
00253 arglist_ [i] = subst;
00254 }
00255 }
00256
00257 return NULL;
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 int exprOp::shrink_arglist (CouNumber c, CouNumber null_element) {
00301
00302 register int i=0, j=0;
00303
00304 bool one_fun = false;
00305
00306
00307 while ((i < nargs_) && (arglist_ [i]))
00308 i++;
00309
00310
00311 if (i==nargs_)
00312 return 0;
00313
00314
00315 for (register int k=nargs_; k--;)
00316 if (arglist_ [k]) {
00317 one_fun = true;
00318 break;
00319 }
00320
00321
00322
00323 if ((fabs (c - null_element) > COUENNE_EPS) || !one_fun)
00324 arglist_ [i++] = new exprConst (c);
00325
00326 j = i;
00327
00328
00329 while (i < nargs_) {
00330
00331 while ((i < nargs_) && !(arglist_ [i]))
00332 i++;
00333
00334 if (i < nargs_)
00335 one_fun = true;
00336
00337 while ((i < nargs_) && (arglist_ [i]))
00338 arglist_ [j++] = arglist_ [i++];
00339 }
00340
00341 nargs_ = j;
00342
00343
00344
00345 return (nargs_ == 1);
00346 }