Can’t sleep: My mind is wandering about in my skull, a kitty among the bins. I can’t make up my mind how to represent an atomic algebraic expression term.

Clearly, an expression term, and an elementary binary operator are two different kinds of objects. What do I make, then, of an expression term such as sin(x)? It’s a function operator taking a single argument. I’d like to be able to manipulate a pair of rational expressions like


How about 2x? It’s an elementary product expression consisting of a constant and a variable. I’m beginning to think each subexpression ought to be represented as an object, now – so that I could replace the factor 2 with an expression, for example. This pretty much puts paid to representing an algebraic polynomial term as a struct:

struct Monomial {
    integer coeff;
    Variable x;
    Exponent t;

Each member coeff, x,  and t would then be an Expr:

struct Monomial {
    Expr coeff;
    Expr x;
    Expr t;

Then I should represent elementary operations as functors as well, perhaps. Hmm. This eliminates the need for a Monomial type:

Expr x('x'), X;
X = 2 * x ^ 3;
cout << X.strict().toString() << endl; // 2*(x^3)
cout << X.toHumanString() << endl; // 2x3
cout << X.toMathML() << endl; // Something like 2x(super)3

I need to look into operator associativity rules and find out whether any combination of member and nonmember functions will cause type coercion of the RHS into an Expr type.


My goal is to be able to create simple code to generate elementary algebra expressions programmatically, like so:

Expr a('a', '1/(x+2)');
Expr b('b', '2/(x+7)');
Expr c;
c = a * b;
cout << c.toMathML() << endl;
cout << c.execute().toMathML() << endl; // 1/(x^2 + 9x + 14)

Then a simple, short chunk of code could do and generate an online algebra workbook of arbitrary complexity:

string generate_rational_fraction_sum( int terms, int glbpower, int lubpower ) {
  Expr rfs;
  Expr numerator;
  Expr denominator;
  Expr monomial('x');
  for ( int i = 0 ; i < terms ; i++ ) {
    integer r = rand(glbpower, lubpower);
    integer q = rand(1,10);
    for ( int j = 0 ; j < r ; j++ ) {
      // Generate an order-j polynomial expression for the denominator
      integer k = rand(1,10);
      denominator += k * monomial ^ j;
    numerator = rand(1,10);
    rfs += numerator / denominator;
  return rfs.execute().toMathML();