Expression Expression::simplify() const { Expression postfactor = *this; Expression prefactor = postfactor.ScalarFactor(); if (prefactor != Expression(1)) { return prefactor * postfactor.simplify(); } if (name == "*" && arg2->name == "*") { if (arg2->arg1->kindIs("constant")) return (*arg2->arg1 * *arg1 * *arg2->arg2).simplify(); if (arg2->arg2->kindIs("constant")) return (*arg2->arg2 * *arg1 * *arg2->arg1).simplify(); return (*arg1 * *arg2->arg1 * *arg2->arg2).simplify(); } if (kindIs("unary") && name == "-") { Expression minusthis = arg1->simplify(); if (minusthis.kindIs("*/") && minusthis.arg1->kindIs("constant")) { minusthis.arg1 = new Expression(-minusthis.arg1->value); return minusthis; } if (minusthis.kindIs("*/") && minusthis.arg1->kindIs("*/") && minusthis.arg1->arg1->kindIs("constant")) { minusthis.arg1->arg1 = new Expression(-minusthis.arg1->arg1->value); return minusthis; } return -minusthis; } Expression out; out.name = name; out.type = type; out.kind = kind; out.alias = alias; if (arg1) out.arg1 = new Expression(arg1->simplify()); if (arg2) out.arg2 = new Expression(arg2->simplify()); if (arg3) out.arg3 = new Expression(arg3->simplify()); return *this; }
Expression Expression::ScalarFactor() { if (kindIs("constant")) { Expression out(value); value = 1; return out; } if (typeIs("double")) { // If we have type "double" then we *are* a scalar! Expression out(*this); *this = Expression(1); return out; } if (kindIs("*/") && name == "*") { Expression sf1 = arg1->ScalarFactor(); Expression sf2 = arg2->ScalarFactor(); *this = *arg1 * *arg2; // to handle cases where arg1 or arg2 becomes 1. return sf1*sf2; } if (kindIs("*/") && name == "/") { Expression sf1 = arg1->ScalarFactor(); Expression sf2 = arg2->ScalarFactor(); *this = *arg1 / *arg2; // to handle cases where arg1 or arg2 becomes 1. return sf1/sf2; } if (kindIs("linear function")) { return arg1->ScalarFactor(); } if (kindIs("unary") && name == "-") { Expression postfactor = *arg1; Expression prefactor = postfactor.ScalarFactor(); *this = postfactor; return -prefactor; } return Expression(1); }