FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious example

Preprocessing Mosel code

Description
It is possible to use standard C preprocessors such as cpp or m4 with Mosel. Mosel treats the preprocessor symbol '#' at the beginning of lines like a comment sign, with the exception of line numbers/positioning markers that are handled to obtain the original line numbers (see the discussion in Section 2.5.3 Line control directives of the Mosel Language Reference Manual).
  • Using a C preprocessor as prefix in compilation:
    mosel comp "mmsystem.pipe:cpp preproc.mos -DA=1 -DDEBUG" -o preprocout.bim
    mosel run preprocout
  • Using a C preprocessor to output model source:
    cpp preproc.mos -DA=1 -DDEBUG -o preprocout.mos
    mosel preprocout.mos
Template substitution: The Mosel program 'template.mos' implements a substitution mechanism that automatically specializes Mosel code by duplicating code portions, such as generating multiple versions of subroutines for different types. The file 'testtemplate_templ.mos' contains some examples of its use (see instructions in the respective file headers).


Source Files
By clicking on a file name, a preview is opened at the bottom of this page.
preproc.mos[download]
template.mos[download]
testtemplate_templ.mos[download]





testtemplate_templ.mos

(!*******************************************************
  Mosel Template Preprocessor
  ===========================

  file testtemplate_templ.mos
  ---------------------------

  -- Testing the Mosel code preprocessing through template.mos --

  This file must be processed through the Mosel program template.mos with
    mosel template INPUT=testtemplate_templ.mos OUTPUT=testtempate.mos
  or:
    mosel template.mos -- testtemplate_templ.mos testtempate.mos

  The resulting file testtemplate.mos can then be run as usual with Mosel.

  (c) Copyright 2024 Fair Isaac Corporation
      author: S. Heipcke
*******************************************************!)

model "testing template processing"
 uses "mmsystem"

 !**** Replacing a single template marker

  !#test.template=true
  !#test.substitute _TYPE_=integer,real,boolean,date,datetime
  public function listcompare(a, b: list of _TYPE_): boolean
    returned:=(a.size=b.size)
    if not returned then
      writeln("Size is different")
    else
      forall(i in 1..a.size)
        if a(i)<>b(i) then
          writeln(formattext("Difference in element %d: %s %s", i, 
                  text(a(i)), text(b(i))))
          returned:=false
	  break
        end-if
    end-if
  end-function
  !#test.template=false

 !**** Replacing multiple template markers

  !#test.template=true
  !#test.substitute _TYPE1_=string,text _TYPE2_=string,text
  public function listcompare(a: list of _TYPE1_, b: list of _TYPE2_): boolean
    returned:=(a.size=b.size)
    if not returned then
      writeln("Size is different")
    else
      forall(i in 1..a.size)
        if a(i)<>b(i) then
          writeln(formattext("Difference in element %d: %s %s", i, a(i),b(i)))
          returned:=false
	  break
        end-if
    end-if
  end-function
  !#test.template=false

 !**** Testing some versions of the generated subroutines ****
  L1:=[1,2,3,4,5]; L2:=[1,2,3,5]
  writeln("L1=L2: ", listcompare(L1,L2))

  declarations
    DL1,DL2: list of date
  end-declarations
  DL1:=sum(d in 1..5) [date(2024,3,d)]
  DL2:=sum(d in 0..4) [date(19783+d)]
  writeln("DL1=DL2: ", DL1=DL2, "/", listcompare(DL1,DL2))

  declarations
    LS: list of string
    LT: list of text
  end-declarations
  LS:=['a','b','C']
  LT:=[text('a'),text('b'),text('C')]
  writeln("LS=LT: ", LS=LT, "/", listcompare(LS,LT))
end-model

Back to examples browserPrevious example