00001 /* $Id: simplifiers.cpp 154 2009-06-16 18:52:53Z pbelotti $ */ 00002 /* 00003 * Name: simplifiers.cpp 00004 * Author: Pietro Belotti 00005 * Purpose: simplifiers for main operators (+,*,-) 00006 * 00007 * (C) Carnegie-Mellon University, 2006. 00008 * This file is licensed under the Common Public License (CPL) 00009 */ 00010 00011 #include "exprOp.hpp" 00012 #include "exprConst.hpp" 00013 #include "CouennePrecisions.hpp" 00014 00015 00016 // 00017 // shrink argument list 00018 // 00019 // used by + and * (for now), accepts a constant resulting from 00020 // applying an operator to the constants in the list of (pointers to) 00021 // function arguments contained in el. The constant is inserted in the 00022 // list if the result is not equal to null_element or if there are 00023 // other non-constant terms in the arglist. 00024 // 00025 // Example: f(x) + 3 + g(x) + 2 + 4 00026 // 00027 // el = {pf, NULL, pg, NULL, NULL} 00028 // nargs = 5 00029 // c = 3 + 2 + 4 = 9 00030 // null_element = 0 (for sums) 00031 // 00032 // where pf and pg are pointers to expression containing f and g, 00033 // resp. 00034 // 00035 // Result: el and nargs are changed to 00036 // 00037 // el = {pf, p9, pg} 00038 // nargs = 3 00039 // 00040 // Another example: f(x) + 2 + g(x) + (-4) + 2 00041 // Result: 00042 // el = {pf, pg} 00043 // nargs = 2 00044 // 00045 // Another example: f(x) * 3 * g(x) * 2 00046 // 00047 // el = {pf, NULL, pg, NULL} 00048 // nargs = 4 00049 // c = 3 * 2 = 6 != null_element = 1 (for multiplications) 00050 // Result: 00051 // el = {pf, p6, pg} 00052 // nargs = 3 00053 // 00054 00055 int exprOp::shrink_arglist (CouNumber c, CouNumber null_element) { 00056 00057 register int i=0, j=0; 00058 00059 bool one_fun = false; 00060 00061 // find first NULL spot (left by some constant) 00062 while ((i < nargs_) && (arglist_ [i])) 00063 i++; 00064 00065 // no spots, leave 00066 if (i==nargs_) 00067 return 0; 00068 00069 // check if there is at least one non-constant expression 00070 for (register int k=nargs_; k--;) 00071 if (arglist_ [k]) { 00072 one_fun = true; 00073 break; 00074 } 00075 00076 // add constant term if c is not null w.r.t. the operation or if it 00077 // would be an empty operand list otherwise 00078 if ((fabs (c - null_element) > COUENNE_EPS) || !one_fun) 00079 arglist_ [i++] = new exprConst (c); 00080 00081 j = i; 00082 00083 // now shift back all operands to compress argument list 00084 while (i < nargs_) { 00085 00086 while ((i < nargs_) && !(arglist_ [i])) 00087 i++; 00088 00089 if (i < nargs_) 00090 one_fun = true; 00091 00092 while ((i < nargs_) && (arglist_ [i])) 00093 arglist_ [j++] = arglist_ [i++]; 00094 } 00095 00096 nargs_ = j; 00097 00098 // only say shrinking simplified arg list if there is just the 00099 // constant 00100 return (nargs_ == 1);// && ((fabs (c - null_element) > COUENNE_EPS) || !one_fun)); 00101 }