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
00018 #include <cstdio>
00019
00020 using namespace Couenne;
00021
00022 namespace Couenne {
00023 class CouenneProblem;
00024 class Domain;
00025 }
00026
00027
00028 exprOp::~exprOp () {
00029
00030 if (arglist_) {
00031 for (expression **alist = arglist_; nargs_--; alist++)
00032 if (*alist) delete (*alist);
00033 delete [] arglist_;
00034 }
00035 }
00036
00037
00038
00039
00040 void exprOp::print (std::ostream &out,
00041 bool descend) const {
00042
00043 if (printPos () == PRE)
00044 out << printOp ();
00045
00046 if (nargs_ > 1)
00047 {out << "("; fflush (stdout);}
00048 for (int i=0; i<nargs_; i++) {
00049 if (arglist_ [i])
00050 arglist_ [i] -> print (out, descend);
00051 fflush (stdout);
00052 if (i < nargs_ - 1) {
00053 if (printPos () == INSIDE) out << printOp ();
00054 else out << ",";
00055 }
00056 if (!((i + 1) % MAX_ARG_LINE))
00057 out << std::endl;
00058 fflush (stdout);
00059 }
00060 if (nargs_ > 1) {
00061 out << ")";
00062 fflush (stdout);
00063 }
00064 }
00065
00066
00068
00069 int exprOp::compare (exprOp &e1) {
00070
00071 int c0 = code (),
00072 c1 = e1. code ();
00073
00074 if (c0 < c1) return -1;
00075 if (c0 > c1) return 1;
00076
00077
00078 if (nargs_ < e1.nargs_) return -1;
00079 if (nargs_ > e1.nargs_) return 1;
00080
00081
00082 for (register int i = nargs_; i--;) {
00083
00084 int res = arglist_ [i] -> compare (*(e1. ArgList () [i]));
00085 if (res) return res;
00086 }
00087
00088
00089 if ((c0 == COU_EXPRGROUP) ||
00090 (c0 == COU_EXPRQUAD)) {
00091
00092 exprGroup *ne0 = dynamic_cast <exprGroup *> (this),
00093 *ne1 = dynamic_cast <exprGroup *> (&e1);
00094
00095 int cg = ne0 -> compare (*ne1);
00096
00097 if (cg) return cg;
00098
00099
00100
00101 if (c0 == COU_EXPRQUAD) {
00102
00103 exprQuad *ne0 = dynamic_cast <exprQuad *> (this),
00104 *ne1 = dynamic_cast <exprQuad *> (&e1);
00105
00106 return ne0 -> compare (*ne1);
00107 }
00108 }
00109
00110 return 0;
00111 }
00112
00113
00115
00116 int exprOp::rank () {
00117
00118 int maxrank = -1;
00119
00120 for (expression **al = arglist_ + nargs_;
00121 al-- > arglist_;) {
00122 int r = (*al) -> rank ();
00123 if (r > maxrank) maxrank = r;
00124 }
00125
00126 return (maxrank);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 exprAux *exprOp::standardize (CouenneProblem *p, bool addAux) {
00141
00142 exprVar *subst;
00143
00144 for (int i = nargs_; i--;)
00145 if ((subst = arglist_ [i] -> standardize (p))) {
00146 if ((subst -> Type () == VAR) ||
00147 (subst -> Type () == AUX))
00148 arglist_ [i] = new exprClone (subst);
00149 else arglist_ [i] = subst;
00150 }
00151 return NULL;
00152 }
00153
00154
00156 void exprOp::replace (exprVar *x, exprVar *w) {
00157
00158 expression **al = arglist_;
00159 int index = x -> Index ();
00160
00161 for (register int i = nargs_; i--; al++)
00162
00163 switch ((*al) -> Type ()) {
00164
00165 case AUX:
00166 case VAR:
00167 if ((*al) -> Index () == index) {
00168 delete *al;
00169 *al = new exprClone (w);
00170 }
00171 break;
00172
00173 case UNARY:
00174 case N_ARY:
00175 (*al) -> replace (x, w);
00176 break;
00177
00178 default:
00179 break;
00180 }
00181 }
00182
00183
00185 bool exprOp::isInteger () {
00186
00187 for (int i = nargs_; i--;)
00188
00189 if (!(arglist_ [i] -> isInteger ())) {
00190
00191
00192
00193 CouNumber lb, ub;
00194 arglist_ [i] -> getBounds (lb, ub);
00195
00196 if ((fabs (lb - ub) > COUENNE_EPS) ||
00197 !::isInteger (lb))
00198 return false;
00199 }
00200
00201 return true;
00202 }
00203
00204
00207 int exprOp::DepList (std::set <int> &deplist,
00208 enum dig_type type) {
00209 int tot = 0;
00210
00211
00212
00213 for (int i = nargs_; i--;) {
00214
00215
00216
00217
00218
00219
00220
00221 tot += arglist_ [i] -> DepList (deplist, type);
00222
00223
00224
00225
00226 }
00227
00228 return tot;
00229 }
00230
00232 void exprOp::realign (const CouenneProblem *p) {
00233
00234 for (int i=0; i<nargs_; i++)
00235 arglist_ [i] -> realign (p);
00236 }