This page is for an old version of Hexaly Optimizer. We recommend that you update your version and read the documentation for the latest stable release.

Modeler

Object-oriented C++ APIs are provided for the virtual machine powering the LSP language. With only a few classes, you can load modules, interact with their variables and execute them. If you are not familiar with the LSP language, please have a look at the language reference for more information.

Create and execute a module

First, you have to create a LSPModeler environment. It is the main class of the Modeler library and allows you to create a module in one of two ways:

Both of these methods return an instance of LSPModule which will enable you to interact with the module variables and functions. To be runnable, a module must implement a model function that will build a LSModel. You can then call LSPModule::run() to start the execution of the module. After the LocalSolver model has been built, the resolution process will be started. You can also import arguments in a module with the method LSPModule::parseArguments(). This method imports each passed argument as a global variable in the module:

LSPModeler modeler;
LSPModule module = modeler.loadModule("my_lsp_file.lsp")
module.parseArguments({"lsIterationLimit=100", "lsTimeLimit=10"})
module.run()

Interacting with variables

You can interact with the variables inside a module thanks to getters and setters on the LSPModule class. Values can be obtained in their native type or retrieved as LSPValue which is a container that can hold any type of value inside a module. For more information on value types available in the modeler you can look at LSPType.

You can create maps from the modeler instance with LSPModeler::createMap(). A Map is a data structure holding (key, value) pairs that can also be used as an array. For more information on maps you can look at the map module.

Using external functions

You can use your own C++ functions as LSP functions in the modeler thanks to the method LSPModeler::createFunction(). First you have to extend the LSPFunctor class and implement the call() function:

class MyLspFunction : public LSPFunctor {
    LSPValue call(LSPModeler& modeler, const std::vector<LSPValue>& arguments) {
        lsdouble result = arguments[0].asDouble() + arguments[1].asDouble();
        return modeler.createDouble(result);
    }
}

MyLspFunction myFunc;
LSPFunction lspFunc = modeler.createFunction(&myFunc);
LSPValue args[2] = {modeler.createDouble(1.5), modeler.createDouble(2.3)};
LSPvalue result = lspFunc.call(args, 2);
std::cout << "result = " << result.asDouble() << std::endl; // prints "result = 3.8"

In the snippet above we declare an LSP function that takes two LSP doubles as input, adds them together and returns the result. We can then call the function with LSPFunction::call() to execute the function and retrieve the result.

You can also assign the function to a variable in a module with LSPModule::setFunction(). After doing so, the function will be callable within any function of the module.