IBM ILOG Solver User's Manual > Developing Solver Applications > Debugging and Tracing > Creating your own trace

You can also create your own trace by subclassing the virtual functions of IlcTraceI. Here is an example:

class MyTraceI : public IlcTraceI {
public:
  MyTraceI(IloSolver solver, IlcUInt flags, const char* name=0) :
      IlcTraceI(solver.getManager().getImpl(),flags,name){}
      ~MyTraceI(){}
 
      // virtual functions
      void beginSetMinIntVar(const IlcIntExp var, IlcInt min){
        var.getSolver().out() << "mySetMinIntVar";
        print(var,min);
      }
      void beginSetValueIntVar(const IlcIntExp var, IlcInt val){
        var.getSolver().out() << "mySetValue";
        print(var,val);
      }
 
      void print(const IlcIntExp var, IlcInt val){
        var.getSolver().out()<< var << " val:" << val << endl;
        IlcGoalI* goal=var.getSolver().getActiveGoal().getImpl();
        IlcDemonI* demon=getActiveDemon().getImpl();
        if (goal == 0) var.getSolver().out() << "no active goal" << endl;
        else var.getSolver().out() << "goal:" << *goal << endl;
        if (demon == 0) var.getSolver().out() << "no active demon" << endl;
        else {
          if (demon->isAConstraint()){
            var.getSolver().out() << "the active demon is the constraint:" << *demon << endl;
          } else {
            var.getSolver().out() << "propagation of demon" << endl;
            if (demon->getConstraintI() == 0){
              var.getSolver().out() << "the demon has no constraint associated with" << endl;
            } else {
              var.getSolver().out() << "the associated constraint with the demon is:";
              var.getSolver().out() << *(demon->getConstraintI()) << endl;
            }
          }
        }
      }
};
 
class MyTrace : public IlcTrace {
public:
  MyTrace(IloSolver solver, IlcUInt flags=4, const char* name=0)
    : IlcTrace() {
      _impl = new (solver.getHeap()) MyTraceI(solver, flags, name);
    }
 
    MyTrace(MyTraceI* impl) {
      _impl = impl;
    }
    ~MyTrace(){}
    MyTraceI* getImpl() const {
      return (MyTraceI*)_impl;
    }
    const MyTrace& trace(IlcIntVar var) const{
      getImpl()->trace(var);
      return *this;
    }
    void operator=(const MyTrace& tr){
      _impl = tr._impl;
    }
};
 
 

This trace must be wrapped using the macro ILOCPTRACEWRAPPER. (See "Tracing variable processing" for an example of how to do this.) It can then be called in an application, as follows:

  MyTrace trace(solver,IlcTraceAllEvent);
  trace.trace(svars[1]);

This produces the following output:

mySetMinIntVarE[0 2..8] val:2
no active goal
propagation of demon
the associated constraint with the demon is:IlcAllDiff(00ACED48) {S[9], M[1], N[2..8], D[2..8], E[0 2..8], O[0], R[0 2..8], Y[0 2..8], }
mySetMinIntVarE[2..7] val:3
no active goal
the active demon is the constraint:(IlcArraySumI(00ACF070)[9022..9088] == (IlcArraySumI(00ACEF38)[9272..9728] - 91 * E[2..7]))
mySetMinIntVarE[3..7] val:4
no active goal
the active demon is the constraint:(IlcArraySumI(00ACF070)[9022..9088] ==
(IlcArraySumI(00ACEF38)[9362..9728] - 91 * E[3..7]))
IlcOr   : 1
mySetValueE[4..7] val:4
goal:IlcIntVarSetValue
no active demon
IlcFail : 1
mySetMinIntVarE[4..7] val:5
goal:IlcIntVarRemoveValue
no active demon
IlcOr   : 2
mySetValueE[5..7] val:5
goal:IlcIntVarSetValue
no active demon