Mosel Language overview
Topics covered in this chapter:
Structure of a Mosel model
A Mosel model (text file with extension .mos) has the form
model model_name Compiler directives Parameters Body end-model
- Compiler directives
-
- Options are specified as a compiler directive, at the beginning of the model
- Options include explterm, which means that each statement must end with a semi-colon, and noimplicit, which forces all objects to be declared
options explterm options noimplicit
- uses statements are also compiler directives
uses "mmxprs", "mmodbc"
- Can define a version number for your model
version 1.0.0
- Another set of compiler directives serves for the definition and configuration of namespaces
namespace mynsp nssearch myns2
- Run-time parameters
-
- Scalars (of type integer, real, boolean, or string) with a specified default value
- Their value may be reset when executing the model
- Use initializations from for inputting structured data (arrays, sets,...)
- At most one parameters block per model
- Model body
-
- Model statements other than compiler directives and parameters, including any number of
- declarations
- initializations from / initializations to
- functions and procedures
- Model statements other than compiler directives and parameters, including any number of
- Implicit declaration
-
- Mosel does not require all objects to be declared
- Simple objects can be used without declaring them, if their type is obvious
- Use the noimplicit option to force all objects to be declared before using them (see item Compiler directives above)
- Mosel statements
-
- Can extend over several lines and use spaces
- However, a line break acts as an expression terminator
- To continue an expression, it must be cut after a symbol that implies continuation (e.g. + - , * )
Data structures
array, set, list, record and any combinations thereof, e.g.,
S: set of list of integer A: array(range) of set of real
- Arrays
-
Array: collection of labeled objects of a given type where the label of an array entry is defined by its index
tuple
declarations A: array(1..5) of real B: array(range, set of string) of integer x: array(1..10) of mpvar end-declarations A:: [4.5, 2.3, 7, 1.5, 10] A(2):= 1.2 B:: (2..4,["ABC", "DE", "KLM"])[15,100,90,60,40,15,10,1,30]
- Sets
-
Set: collection of objects of the same type without establishing an order among them (as opposed to arrays and lists)
Set elements are unique: if the same element is added twice the set still only contains it once.declarations S: set of string R: range end-declarations S:= "A", "B", "C", "D" R:= 1..10
- Lists
-
List: collection of objects of the same type
A list may contain the same element several times. The order of the list elements is specified by construction.declarations L: list of integer M: array(range) of list of string end-declarations L:= [1,2,3,4,5] M:: (2..4)[['A','B','C'], ['D','E'], ['F','G','H','I']]
- Records
-
Record: finite collection of objects of any type
Each component of a record is called a field and is characterized by its name and its type.declarations ARC: array(ARCSET:range) of record Source,Sink: string ! Source and sink of arc Cost: real ! Cost coefficient end-record end-declarations ARC(1).Source:= "B" ARC(3).Cost:= 1.5
- User types
-
User types are treated in the same way as the predefined types of the Mosel language. New types are defined in
declarations blocks by specifying a type name, followed by
=, and the definition of the type.
declarations myreal = real myarray = array(1..10) of myreal COST: myarray end-declarations
- Union types
-
Union: container capable of holding an object of one of a predefined set of types.
Defined by specifying the set of compatible types or the predefined union type any.declarations u: string or real ! Scalar accepting 'string' or 'real' a: any ! Scalar accepting any type ! Defining a type name for the union of the 4 basic Mosel types: basictype = string or integer or real or boolean U: array(range) of basictype ! Array of union type 'basictype' end-declarations
Selection statements
- if ... end-if
-
if c=1 then writeln('c equals 1') end-if
- if ... else ... end-if
-
if c=1 then writeln('c equals 1') else writeln('c does not equal 1') end-if
- if ... elif ... else ... end-if
-
if c=1 then writeln('c equals 1') elif c1 then writeln('c is bigger than 1') else writeln('c is smaller than 1') end-if
- case ... end-case
-
case c of 1,2 : writeln('c equals 1 or 2') 3 : writeln('c equals 3') 4..6: do writeln('c is in 4..6') writeln('c is not 1, 2 or 3') end-do else writeln('c is not in 1..6') end-case
Loops
- forall
-
forall(f in FAC, t in TIME) make(f,t) = MAXCAP(f,t) forall(t in TIME) do use(t) = MAXUSE(t) buy(t) = MAXBUY(t) end-do
- with
-
equivalent to a
forall loop stopped after the first iteration
with f='F1', t=1 do make(f,t) = MAXCAP(f,t) end-do
- while
-
i := 1 while (i = 10) do write(' ', i) i += 1 end-do
- repeat ... until
-
i := 1 repeat write(' ', i) i += 1 until (i 10)
- break, next
-
- break jumps out of the current loop
- break n jumps out of n nested loops (where n is a positive integer)
- next jumps to the beginning of the next iteration of the current loop
- counter
-
- Use the construct as counter to specify a counter variable in a bounded loop (i.e., forall or aggregate operators such as sum). At each iteration, the counter is incremented
cnt:=0.0 writeln("Average of odd numbers in 1..10: ", (sum(cnt as counter, i in 1..10 | isodd(i)) i) / cnt)
Operators
- Assignment operators
-
i := 10 i += 20 ! Same as i := i + 20 i -= 5 ! Same as i := i - 5
- Assignment operators with linear constraints
-
C := 5*x + 2*y = 20 D := C + 7*y
then D isD := 5*x + 9*y - 20
The constraint type is dropped with :=C := 5*x + 2*y = 20 C += 7*y
then C isC := 5*x + 9*y = 20
The constraint type is retained with +=, -= - Arithmetic operators
-
standard: + - * / power: ^ int. division/remainder: mod div sum: sum(i in 1..10) ... product: prod(i in 1..10) ... minimum/maximum: min(i in 1..10) ... count: count(i in 1..10 | isodd(i)) - Linear and non-linear expressions
-
Decision variables can be combined into linear or non-linear expressions using the arithmetic operators- module mmxprs only works with linear constraints, so no prod, min, max, ...
- other solver modules, e.g., mmnl, mmxnlp, also accept (certain) non-linear expressions
- Logical operators
-
constants: true, false standard: and, or, not AND: and(i in 1..10) ... OR: or(i in 1..10) ... comparison: <, >, =, <>, <=, >= - Set operators
-
constants: {'A', 'B'} union: + union: union(i in 1..10) ... intersection: * intersection: inter(i in 1..10) ... difference: - - Set comparison operators
-
subset: Set1 <= Set2 superset: Set1 >= Set2 equals: Set1 = Set2 not equals: Set1 <> Set2 element of: "Oil5" in Set1 not element of: "Oil5" not in Set1 - List operators
-
constants: [1, 2, 3] concatenation: +, sum truncation: - equals: L1 = L2 not equals: L1 <> L2 enumeration: i in L (within forall, sum etc.) - Union and reference operators
-
testing properties of unions:! u declared as a union type, such as 'any' writeln(u is array of integer) writeln(u is not procedure)
'reference to' operator:L:= [-cos,-sin,-arctan,-exp] forall(f in L) writeln(f(0.5))
Built in functions and procedures
The following is a list of built in functions and procedures of the Mosel language (excluding modules). Functions return a value; procedures do not.
- Dynamic array handling
-
create exists delcell isdynamic
- Freeze (finalize) a dynamic set
-
finalize
- Rounding functions
-
ceil floor round abs
- Mathematical functions
-
exp log ln sqrt cos sin arctan isodd
- Special real values
-
isfinite isinf isnan
- Random number generator
-
random setrandseed
- Minimum/maximum of a list of values
-
v := minlist(5, 7, 2, 9) w := maxlist(CAP(1), CAP(2))
- Inline ``if'' function
-
MAX_INVEN(t) := if(t MAX_TIME, 1000, 0) Inven(t) := stock(t) = buy(t) - sell(t) + if(t 1, stock(t-1), 0)
- Matrix export to file
-
exportprob ! Outputs LP/MIP portion handled by ! Mosel core; use solver-specific routines such as ! 'writeprob' of mmxprs for complete matrix output
- File handling
-
fopen fclose fselect getfid getfname getreadcnt iseof fflush fskipline fwrite[_] / fwriteln[_] read / readln write[_] / writeln[_]
- String handling
-
strfmt substr _
- Access and modify model objects
-
getcoeff[s] setcoeff getvars gettype settype makesos1 makesos2 sethidden ishidden setname setrange getnbdim getsize getelt getfirst getlast findfirst findlast gethead gettail cutelt cutfirst cutlast cuthead cuttail reverse getreverse splithead splittail
- Access solution values
-
getobjval getsol getrcost getslack getact getdual
- Exit from a model
-
exit
- Mosel controls
-
getparam setparam localsetparam restoreparam
- Date/time
-
currentdate currenttime timestamp
- Bit value handling
-
bitflip bitneg bitset bitshift bittest bitval
- Handling unions
-
geteltype getstruct gettypeid isdefined
- Miscellaneous
-
asproc assert compare datablock dumpcallstack memoryuse newmuid publish unpublish reset setioerr setmatherr versionnum versionstr
- Overloading of subroutines
- Some functions or procedures are overloaded: a single subroutine can be called with different types and numbers of arguments
- Additional subroutines are provided by Mosel library modules, which extend the basic Mosel language, e.g.,
- mmxprs: Xpress Optimizer
- mmodbc: ODBC data connection
- mmsheet: accessing spreadsheets
- mmsystem: system calls; text handling; date and time types
- mmjobs: handling multiple models and (remote) Mosel instances
- mmsvg: graphics
- User-defined functions and procedures
- You can also write your own functions and procedures within a Mosel model
- Structure of subroutines is similar to a model (may have declarations blocks)
- User subroutines may define overloaded versions of built in subroutines
- Packages
- Additional subroutines may also be provided through packages (Mosel libraries written in the Mosel language as opposed to Mosel modules that are implemented in C)
Constraint handling
Ctr1:= 2*x + y = 10 ! Named constraints Ctr2:= x is_integer 2*x + y = 10 ! Anonymous constraints y = 5
- Named constraints can be
-
- accessed:
-
val:= getact(Ctr) getvars(Ctr, vars)
- hidden:
-
sethidden(Ctr, true)
- redefined:
-
Ctr:= x+y = 10 Ctr:= 2*x+5*y = 5
- modified:
-
Ctr += 2*x settype(Ctr, CT_UNB)
- deleted (reset):
-
Ctr:= 0
Anonymous constraints are constraints that are specified without assigning them to a linctr variable. Bounds are (to Mosel) just simple constraints without a name. Anonymous constraints are applied in the optimization problem just like ordinary constraints. The only difference is that it is not possible to refer to them again, either to modify them, or to examine their solution value.
Problem handling
- Mosel can handle several problems in a given model file. A default problem is associated with every model.
- Built in type mpproblem to identify mathematical programming problems
- The same decision variable (type mpvar) may be used in several problems
- Constraints (type linctr) belong to the problem where they are defined
- The statement with allows to open a problem (= select the active problem):
declarations myprob: mpproblem end-declarations ... with myprob do x+y = 0 end-do
mypbtyp = mpproblem and somepbtype
and additive assignment: P1 += P2
© 2001-2025 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.