IBM ILOG Solver User's Manual > More on Modeling > Using Constrained Floating-Point Variables: Modeling Equations > Factored and canonical forms of expressions > Factored and canonical forms: Example 1

Suppose x, y, and z are three variables, and you want to express the following relation:

z = (x - 1)*(y + 2)

There are various ways to express the constraint. You can, for example, write the expression in a factored form like this:

#include <ilsolver/ilosolverfloat.h>

ILOSTLBEGIN

int main() {

  IloEnv env;
  try {
  IloModel model(env);

  IloNumVar x(env, -2, 2), y(env, 0, 10), z(env, -100, 100);
  model.add((x - 1)*(y + 2) == z);
  IloSolver solver(model);
  solver.propagate();
  cout <<  "z = " << solver.getFloatVar(z) << endl;

}
  catch (IloException& ex) {
          cerr << "Error:" << ex << endl;
  }
  env.end();
  return 0;
}

The output is:

z = [-36, 12]

You can write the same expression in a canonical algebraic form, like this:

#include <ilsolver/ilosolverfloat.h>

ILOSTLBEGIN

int main() {

  IloEnv env;
  try {
  IloModel model(env);

  IloNumVar x(env, -2, 2), y(env, 0, 10), z(env, -100, 100);
  model.add(z == x*y - y + 2*x - 2);
  IloSolver solver(model);
  solver.propagate();
  solver.out() << "z = [" << solver.getMin(z)
                          << ", " << solver.getMax(z)
                          << "]" << endl;
}
  catch (IloException& ex) {
          cerr << "Error:" << ex << endl;
  }
  env.end();
  return 0;
}

After propagation, the result is:

z = [-36, 22]

With the factored form, you can see that propagation has more severely reduced the domain of z, and in terms of performance, that is a good thing.

Because of that observation, you might think that it is always better to write constraints in a factored form. However, you will see a counter-example to that hasty generalization.