+ ex en = e.normal();
+ if (!en.is_equal(d)) {
+ clog << "normal form of " << e << " erroneously returned "
+ << en << " (should be " << d << ")" << endl;
+ return 1;
+ }
+ return 0;
+}
+
+static unsigned exam_normal1()
+{
+ unsigned result = 0;
+ ex e, d;
+
+ // Expansion
+ e = pow(x, 2) - (x+1)*(x-1) - 1;
+ d = 0;
+ result += check_normal(e, d);
+
+ // Expansion inside functions
+ e = sin(x*(x+1)-x) + 1;
+ d = sin(pow(x, 2)) + 1;
+ result += check_normal(e, d);
+
+ // Fraction addition
+ e = 2/x + y/3;
+ d = (x*y + 6) / (x*3);
+ result += check_normal(e, d);
+
+ e = pow(x, -1) + x/(x+1);
+ d = (pow(x, 2)+x+1)/(x*(x+1));
+ result += check_normal(e, d);
+
+ return result;
+}
+
+static unsigned exam_normal2()
+{
+ unsigned result = 0;
+ ex e, d;
+
+ // Fraction cancellation
+ e = numeric(1)/2 * z * (2*x + 2*y);
+ d = z * (x + y);
+ result += check_normal(e, d);
+
+ e = numeric(1)/6 * z * (3*x + 3*y) * (2*x + 2*w);
+ d = z * (x + y) * (x + w);
+ result += check_normal(e, d);
+
+ e = (3*x + 3*y) * (w/3 + z/3);
+ d = (x + y) * (w + z);
+ result += check_normal(e, d);
+
+ // Fails stochastically with the new tinfo mechanism, because
+ // sometimes the equivalent answer ... / pow(y - x, 2) is calculated.
+ // TODO: make check for both cases.
+// e = (pow(x, 2) - pow(y, 2)) / pow(x-y, 3);
+// d = (x + y) / pow(x - y, 2);
+// result += check_normal(e, d);
+
+ e = (pow(x, -1) + x) / (pow(x , 2) * 2 + 2);
+ d = pow(x * 2, -1);
+ result += check_normal(e, d);
+
+ // Fails stochastically with the new tinfo mechanism, because
+ // sometimes the equivalent answer ... / pow(y - x, 2) is calculated.
+ // TODO: make check for both cases.
+ // Fraction cancellation with rational coefficients
+// e = (pow(x, 2) - pow(y, 2)) / pow(x/2 - y/2, 3);
+// d = (8 * x + 8 * y) / pow(x - y, 2);
+// result += check_normal(e, d);
+
+ // Fraction cancellation with rational coefficients
+ e = z/5 * (x/7 + y/10) / (x/14 + y/20);
+ d = 2*z/5;
+ result += check_normal(e, d);
+
+ return result;
+}
+
+static unsigned exam_normal3()
+{
+ unsigned result = 0;
+ ex e, d;
+
+ // Distribution of powers
+ e = pow(x/y, 2);
+ d = pow(x, 2) / pow(y, 2);
+ result += check_normal(e, d);
+
+ // Distribution of powers (integer, distribute) and fraction addition
+ e = pow(pow(x, -1) + x, 2);
+ d = pow(pow(x, 2) + 1, 2) / pow(x, 2);
+ result += check_normal(e, d);
+
+ // Distribution of powers (non-integer, don't distribute) and fraction addition
+ e = pow(pow(x, -1) + x, numeric(1)/2);
+ d = pow((pow(x, 2) + 1) / x, numeric(1)/2);
+ result += check_normal(e, d);
+
+ return result;