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:
You can load a module from an existing LSP file with the method
LSPModeler.load_module()
.Or you can create an empty module with the method
LSPModeler.create_module()
.
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.