LocalSolver logo
is now
Hexaly logo

We're excited to share that we are moving forward. We're leaving behind the LocalSolver brand and transitioning to our new identity: Hexaly. This represents a leap forward in our mission to enable every organization to make better decisions faster when faced with operational and strategic challenges.

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 Python 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 an LSPModeler environment. As with the main LocalSolver object, we recommend using a “with” statement that will ensure the native memory allocated for the modeler is correctly released when the environment is discarded. LSPModeler 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.parse_arguments(). This method imports each passed argument as a global variable in the module:

with LSPModeler() as modeler:
    module = modeler.load_module("my_lsp_file.lsp")
    module.parse_arguments("lsIterationLimit=100", "lsTimeLimit=10")
    module.run()

Interacting with variables

The class LSPModule behaves like a dictionnary and you can retrieve, set or create new variables that will be exposed in your LSP code:

module = ...
print(module["lsIterationLimit])
module["lsIterationLimit"] = 100000
module["myVariable"] = "spam, egg and cheese"
module["customData"] = -45.2
# Removing a variable, reset its value to "nil" in LSP
del module["lsIterationLimit"]

Under the hood, LSPModule overloads the special methods LSPModule.__getitem__(), LSPModule.__setitem__() and LSPModule.__delitem__().

These methods can receive or return python values that are transparently transformed to their LSP equivalent. The following python types are supported: boolean, integers, floating point numbers, strings and the special value None (which is transposed to nil in LSP).

If simple values are not sufficient for your usage, you can also create array-like or dictionary-like structures with LSPModeler.create_map(). For more information on maps you can look at the map module.

Using external functions

You can use native Python functions as LSP functions in the modeler thanks to the method LSPModeler.create_function(). The Python function must take a modeler instance as first argument, and LSP values as subsequent arguments. The function can return a value that will be converted and transmitted to the LSP caller:

def my_lsp_function(modeler, arg1, arg2):
    return arg1 + arg2

lsp_func = modeler.create_function(my_lsp_function)
result = lsp_func(1.5, 2.3)
print("result = {}".format(result)) # 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.__setitem__(). After doing so, the function will be callable within any function of the module.