IBM ILOG Solver User's Manual > Extending the Library > Writing a Goal: Car Sequencing > Writing your own goal > Using ILCGOALn to define a new class of goals

You define a goal using the macro ILCGOALn. The definition consists of three parts:

For example, the following goals merely print something, but they are valid goal definitions:

ILCGOAL0(Print){
    cout << "Print: executing a goal without parameters\n";
    return 0;
}
ILCGOAL1(PrintX, IlcInt, x){
    cout << "PrintX: executing a goal with one parameter\n";
    cout << x << endl;
    return 0;
}
ILCGOAL2(PrintXY, IlcInt, x, IlcFloat, y){
    cout << "PrintXY: executing a goal with two parameters\n";
    cout << x << endl;
    cout << y << endl;
    return 0;
}


The definition of a goal defines a function for calling it. In that sense, a goal call is a function call. For example, the following are valid calls of the goals just defined.

Print(solver);
PrintX(solver, 2);
PrintXY(solver, 1, 2.);

The goal calling function can be declared in a header file. Its signature has the same name and parameters as the goal, and it returns a pointer to an object of the type IlcGoal.

Note
Such pointers must not be stored since goals are automatically de-allocated by Solver after they have been executed. They can be passed as arguments as long as the goal has not yet been executed.

For example, the following declarations are valid declarations of these same goals:

IlcGoalI Print(IloSolver solver);
IlcGoalI PrintX(IloSolver solver, IlcInt x);
IlcGoalI PrintXY(IloSolver solver, IlcInt x, IlcFloat y);

You can also define a goal using subgoals. The following goal has three subgoals:

ILCGOAL0(PrintAll){
   IloSolver solver=getSolver();
   return IlcAnd(Print(solver), PrintX(solver, 2), PrintXY(solver, 1, 2.));
}

The execution of the goal PrintAll produces the following output:

Print: executing a goal without parameters
PrintX: executing a goal with one parameter
2
PrintXY: executing a goal with two parameters
1
2