It would also be nice to have a "raw" version of generateCuts that depends on no other COIN libs - but, given most cut implementations will make use of CoinUtils anyway, it is probably fine to use CoinUtils methods and objects. But, this forces Cgl dependence on Coin. Example prototype: ``` class CglCutGenerator{ //--- //--- Input : (1) a description of the feasible region //--- (2) a point to separate //--- Output: (1) a list of separating hyperplanes //--- virtual int generateCuts(const CoinPackedMatrix & matrix, const double * collb, const double * colub, const double * obj, const double * rowlb, const double * rowub, const char * coltype, const double * currSol, vector & cuts, const CglTreeInfo info = CglTreeInfo()) = 0; } ``` For this, the only new thing we'd need is CoinCut - which can just be a replacement for OsiCut - it should not be tied to Osi, since it has nothing specific about any solver. A CoinModel could also help make this cleaner. ``` //or... force them to use something like CoinModel virtual int generateCuts(const CoinModel & model, const double * currSol, vector & cuts, const CglTreeInfo info = CglTreeInfo()) = 0; ``` All the non-solver specific cuts will be derived from CglCutGenerator (as before) - just remove any dependence on Osi. This includes clique, knapsack, flowcover, etc. Then, for deriving solver specific cuts (like Gomory) - we can have a separate library. One that does depend on Osi (and Cgl). Call it libCglOsi. This can also include "wrapper classes" for the base cuts clique, knapsack, etc - so that CglOsi users will have uniformity - as they did before. ``` //--- //--- Cgl depends on Coin (NOT on Osi) //--- CglOsi depends on Coin, Cgl and Osi //--- class CglOsiCutGenerator { private: OsiSolverInterface * si; ... virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cuts, const CglTreeInfo info = CglTreeInfo())=0; } ``` So, an example derivation: ``` class CglOsiGomory : public CglOsiCutGenerator { //this is exactly the same as before, it is dependent on Osi ... }; class CglClique : public CglCutGenerator { //this is exactly the same as before, but no dependence on Osi ... }; class CglOsiClique : public CglOsiCutGenerator { //CglOsiClique is just a wrapper class for CglClique. private: CglClique cglClique; ... virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cuts, const CglTreeInfo info = CglTreeInfo()){ cglClique.generateCuts(si.getMatrixByRow(), si.getColLowerBound(), si.getColUpperBound(), ... ... ); } } ``` In this way, the old users still can just "add cut generators" - this time, they are CglOsiCutGenerator(s), but non-OSI users still have access to cliques, knapsack, etc, via the base classes CglCutGenerator(s).