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.

Values and types

The LSP language is strongly typed. In other words, there is only a limited set of implicit conversions between values of different types. For example, it is not possible to multiply an integer and a string, even if the string itself represents a number (for exemple 4 * "40.3" is not allowed).

As already mentionned, the LSP is also a dynamic language. Thus, the type is hold by the value, not by the variable. Every value has a type, and the type itself is also a value. This is particulary important since almost everything is a value in LSP (included classes, functions and modules).

Standard & common types

Nil

Nil is a particular type. The single value of this type is accessed through the keyword nil. It is used to signify the absence of a value. Nil is the default returned value for functions that don’t explicitly return anything. It’s also the default value assigned by the modeler to every global and local variable. Caution should be taken when dealing with nil: Indeed, only a very small subset of operations is allowed on nil. Every forbidden operation performed on nil will throw an exception.

Booleans

Booleans are written as true and false. Booleans are loosely typed and behave like the integers 1 and 0 in numeric context. Thus, true + 1 is a valid expression equal to 2. Conversely, the integers 1 and 0 are automatically and transparently converted to true and false when a boolean is expected. In other words, when a function expects a boolean value, you can call it with true, false, 1 or 0. Any other integer used as a boolean will throw an error:

if (1) println("foo");   // display "foo". 1 is automatically converted to true when a boolean is expected.
if (-38) println("bar"); // will throw the error "Cannot use a branch instruction with type 'int'."
c = (true + 1)*4;        // c will receive 8 : true is automatically converted to 1.

Integers

Integers are positive and negative integral numbers stored on 64 bits. They are created by integer literals or returned as results of arithmetic operations. Integers are immutable.

The smallest possible integer is -9,223,372,036,854,775,808 and the largest integer is +9,223,372,036,854,775,807. The modeler do not perform any range check: if the result of an operation fall outside of this range, the modeler won’t throw any exception but an integer overflow will occur.

Floats

Floats are double precision floating point numbers (stored on 64 bits) in IEEE 754 binary floating point representation. They are created by floating point literals or returned as results of arithmetic operations. Floats are immutable.

Objects

All values that are not numbers, booleans or nil are objects. The most commonly used objects are strings, maps, files and LSExpressions, for example.

Strings

A string is an immutable sequence of unicode characters stored in UTF-8 format. There is no character type. A character is represented as a string of length 1. See section String module for a description of built-in functions for string management.

Maps

Maps are data structure matching some values to some keys. Keys and values can be of any type except nil that has a special meaning. The value associated to a key is set or retrieved by using the “bracket” notation. For instance, a[k] returns the value associated to the key k from the map a. If there is no value associated to the given key, nil is returned. Setting the value of an existing key will overwrite the previous value associated to the key.

A map is both an associative table and an array. A map is implicitly declared when inserting its first element. Alternatively, an empty map can be defined using map() function or a pair of braces {}. Braces also allow defining a map by giving a sequence of values. In this case these values will be assigned to integer keys 0,1,2,... (see section Map declaration).

See section Map module for a description of built-in functions for map management.

LSExpressions

LSExpressions are the variables and the expressions of the mathematical model defined by the LSP program. They can only be introduced and manipulated with the “link” operator <-. Only expressions introduced or manipulated with this operator are passed to the solver for a resolution.

In the following example x_0, x_1 and knapsackWeight are LS expressions:

x_0 <- bool();
x_1 <- bool();
knapsackWeight <- 10*x_0 + 60*x_1

These expressions are directly passed to the LocalSolver APIs. Consequently, they must follow the rules of the solver. For example, the solver forbids declaring a non-boolean number as a constraint and requires logical operators to apply on boolean values only.

Functions

The LSP language treats functions as first-class citizens. In other words, a function is a value with a particular type. Thus, functions can be passed as arguments to other functions, can be assigned to variables or returned by other functions.

There are two kinds of functions in the LSP language:

  • Native functions. These functions are directly provided by the underlying LSP virtual machine. They are written in a native language like C or C++.

  • User functions. These functions are written with the LSP language. User functions are the only place where local variables can be declared.

The section Functions describes the behavior of functions and how to declare them.

Modules

A module is a collection of classes, functions and global variables. Modules are used to group classes and functions together and import them dynamically at runtime. The I/O library is an example of a module. Each LSP file is a module.

Like functions, LSP treats modules as first-class citizens. Thus, modules can be passed as arguments, assigned to variables…

Other types

The modeler comes with many other types. Please refer to the documentation of each module to have a description of their characteristics.