00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "CouenneProblem.hpp"
00013
00014
00015
00018 void CouenneProblem::flattenMul (expression *mul, CouNumber &coe,
00019 std::map <int, CouNumber> &indices) {
00020
00021 #ifdef DEBUG
00022 printf ("flatten %d ---> ", mul -> code ()); mul -> print ();
00023 printf ("\n");
00024 #endif
00025
00026 if (mul -> code () != COU_EXPRMUL) {
00027
00028 exprAux *aux = mul -> standardize (this);
00029
00030 int ind = (aux) ? aux -> Index () : mul -> Index ();
00031
00032 std::map <int, CouNumber>::iterator
00033 where = indices.find (ind);
00034
00035 if (where == indices.end ())
00036 indices.insert (std::pair <int, CouNumber> (ind, 1));
00037 else ++ (where -> second);
00038
00039 return;
00040 }
00041
00042 int nargs = mul -> nArgs ();
00043 expression **al = mul -> ArgList ();
00044
00045
00046 for (int i=0; i < nargs; i++) {
00047
00048 expression *arg = al [i];
00049
00050 #ifdef DEBUG
00051 printf (" flatten arg %d ---> ", arg -> code ()); arg -> print ();
00052 printf ("\n");
00053 #endif
00054
00055 switch (arg -> code ()) {
00056
00057 case COU_EXPRCONST:
00058
00059 coe *= arg -> Value ();
00060 break;
00061
00062 case COU_EXPRMUL:
00063
00064 flattenMul (arg, coe, indices);
00065 break;
00066
00067 case COU_EXPRVAR: {
00068
00069 std::map <int, CouNumber>::iterator
00070 where = indices.find (arg -> Index ());
00071
00072 if (where == indices.end ())
00073 indices.insert (std::pair <int, CouNumber> (arg -> Index (), 1));
00074 else ++ (where -> second);
00075 } break;
00076
00077 case COU_EXPROPP:
00078
00079 coe = -coe;
00080
00081 if (arg -> Argument () -> Type () == N_ARY) {
00082 flattenMul (arg -> Argument (), coe, indices);
00083 break;
00084 } else arg = arg -> Argument ();
00085
00086 case COU_EXPRPOW:
00087
00088 if (arg -> code () == COU_EXPRPOW) {
00089
00090 expression *base = arg -> ArgList () [0],
00091 *exponent = arg -> ArgList () [1];
00092
00093 if (exponent -> Type () == CONST) {
00094
00095 double expnum = exponent -> Value ();
00096
00097 expression *aux = base -> standardize (this);
00098
00099 if (!aux)
00100 aux = base;
00101
00102 std::map <int, CouNumber>::iterator
00103 where = indices.find (aux -> Index ());
00104
00105 if (where == indices.end ())
00106 indices.insert (std::pair <int, CouNumber> (aux -> Index (), expnum));
00107 else (where -> second += expnum);
00108
00109 break;
00110 }
00111 }
00112
00113 case COU_EXPRSUM:
00114
00115 if ((arg -> code () == COU_EXPRSUM) &&
00116 (arg -> nArgs () == 1)) {
00117
00118 flattenMul (arg, coe, indices);
00119 break;
00120
00121 }
00122
00123 default: {
00124
00125 exprAux *aux = arg -> standardize (this);
00126
00127 int ind = (aux) ? aux -> Index () : arg -> Index ();
00128
00129 std::map <int, CouNumber>::iterator
00130 where = indices.find (ind);
00131
00132 if (where == indices.end ())
00133 indices.insert (std::pair <int, CouNumber> (ind, 1));
00134 else ++ (where -> second);
00135
00136 } break;
00137 }
00138 }
00139 }