Blog Post

FICO® Xpress Optimization Blog
4 MIN READ

Guidelines for Mosel developers: Union types and reflection

FICO's avatar
FICO
Community Manager
3 years ago
The Xpress Mosel language has evolved considerably over more than 20 years since its first release in 2001. Whilst continuously building out the available optimization features by adding support for new Solver features or whole new solvers (such as Constraint Programming with Xpress Kalis, Robust Optimization, Nonlinear Optimization, and coming soon Global Optimization), Mosel is increasingly used for the implementation of large-scale projects (most prominently FICO Decision Optimizer) and general programming tasks. Therefore, recent releases of Xpress Mosel have built out the programming capabilities of the language: in this blog we are going to discuss the concepts of union types and reflection that have been introduced with Mosel 6.

Union types
The Mosel language is a strongly typed language: every entity or subroutine declaration made within the language requires a full specification of types, including the number and types of subroutine arguments and the return type of functions.

When developing Mosel libraries in the form of Mosel packages, for example, some generic data input routines, the actual data type(s) might not be known upfront: in such cases, it is now possible to work with union types instead of some particular type. A union is a container that is capable of holding an object of one or a predefined set of types, or the predefined union type ‘any’ than can handle any type without restriction, for example:



With this new functionality, it has become possible to write Mosel code such as the following (with earlier versions of Mosel this would have resulted in an error message):



Where the list ‚L‘ is implicitly declared as a ‚list of any‘ if it has not been declared previously.
We now also have the ability to define subroutines with a variable number of arguments using the syntax ‚…‘ that can be thought of as a ‚list of any‘.:



The example FICO Xpress Optimization Examples Repository: Dataframe formats shows how to work with union types for reading input data without any prior knowledge of structure and types, using a ‘dataframe’ type representation.

References
When union types are employed for storing or accessing data or other model entities generically  it is often desirable to maintain a link between the container and the original entity:  in the previous code snippets we have seen examples of assignments: if we write a:=r, where 'r' is of a scalar basic type (e.g., a real) the union 'a' receives a copy of the value of 'r', and when 'r' changes, the contents of 'a' remain unchanged. Now, if we actually want 'a' to change if the value of 'r' is modified, this can be achieved by assigning 'a' the reference to 'r', denoted by the operator '->':



The ‚reference to‘ operator can be applied to all types of Mosel entities, including subroutines. In the example optgrid2.mos the user input in textual form configures the choice of a nonlinear function for the formulation of an optimization model with the help of subroutine references.

A useful side-effect of working with subroutine references is the possibility to use such references in the definition of callbacks, that is, the name of the routine implementing the callback is no longer used to locate it and hence, this subroutine no longer needs to be declared as ‚public‘, thus disclosing less information about your program structure, such as in this example of a callback definition for Xpress Optimizer:



Reflection
Reflection or reflective programming is the ability of a program to examine, introspect, and modify its own structure and behavior (see https://en.wikipedia.org/wiki/Reflective_programming). This capability is useful for the creation of generic libraries or also when implementing testing systems. In the context of Mosel, user inputs (such as a model entity name selection or the selection of an execution mode in an Xpress Insight view) can be picked up and applied more easily to modify program execution.

The new Mosel module ‚mmreflect‘ that implements the reflection functionality for the Mosel language provides generic routines for retrieving, inspecting and modifying model entities. It also defines a generic way for enumerating arrays via an ‚iterator‘ type that makes it possible to enumerate arrays without any information regarding their number of dimensions or the type of their indexing sets, such as:



A complete example using this functionality is shown in the package file solarranypkg.mos that is discussed in the Mosel User Guide.

To access training material on modeling and problem solving with Xpress Mosel, follow this link.
Learning videos about Xpress Mosel are available here.

If you are interested in learning more from Susanne make sure to check out her most recent series on new modeling constructs in Mosel that allow for an easier formulation of MIP models and the contribution ‘Xpress Mosel: A 20 Year Success Story’.

In case you haven’t already, make sure to subscribe to our Optimization blog to be notified of more content on this topic. - Look out for the next contributions in this series that will talk about ‘new data handling functionality in Mosel 6’ (including the use of union types in dataframe-style input from CSV or databases) and  ‚new solving and maths features in Mosel 6.4‘.
Updated 3 years ago
Version 3.0
No CommentsBe the first to comment