# Zimpl

Zimpl is a language to translate the mathematical model of a problem into a linear or (mixed-) integer mathematical program expressed in .lp or .mps file format which can be read and (hopefully) solved by a LP or MIP solver.

See http://www.zib.de/koch/zimpl/ for the home page of this tool and examples.

On the above page, a command line tool is provided to read a model written in the Zimpl language and it creates a CPLEX lp file. lp_solve is able to read this generated CPLEX lp file via the xli_CPLEX XLI driver, but that would require an extra step.
lp_solve can read/write and solve these Zimpl models directly via the xli_Zimpl XLI driver (see External Language Interfaces). It reads such a model in above format and can solve it then.
Also note that the XLI driver depends on an external dll: zlib1.dll. When it cannot be found on the system, an appropriate message will be given. This dll must be in a directory specified by the Path environment variable. A common place is c:\windows\system32. The dll is distributed with the package. The latest version can be found at http://www.zlib.net/
For example:

    lp_solve -rxli xli_Zimpl chvatal_diet.zpl

This gives as result:

    Value of objective function: 97

    Actual values of the variables:
    x$Oatmeal                       4
    x$Chicken                       0
    x$Eggs                          0
    x$Milk                          5
    x$Pie                           2
    x$Pork                          0

#### Options

The XLI accepts several options:

      -b             Enable Bison (Lex parser) debugging output.
      -D name=value  Sets the parameter name to the specified value.
                     This is equivalent with having this line in the ZIMPL program: param name:=val.
      -f             enable flex debugging output.
      -n cm|cn|cf    name column make/name/full
      -O             Try to reduce the generated LP by doing some presolve analysis.
      -s seed        Positive seed number for the random number generator.
      -v[0-5]        Set the verbosity level. 0 is quiet, 1 is default, 2 is verbose, 3 and 4 are chatter, and 5 is debug.
      -V             show version info

These options are the same as the stand-alone zimpl program.

The lp_solve command line program can provide these parameters via the -rxliopt argument.
For example:

    lp_solve -rxli xli_Zimpl chvatal_diet.zpl -rxliopt "-v0 -O"

#### Generating ZIMPL models

The XLI can also create a ZIMPL model, however it doesn't use the strength of the language. Constraints are written out line per line. But it can be a starter. For example:

    lp_solve model.lp -wxli xli_Zimpl model.zpl

This gives as model.zpl:

    # Variable definitions
    var x >= 0;
    var y >= 0;

    # Objective function
    maximize obj: +143*x +60*y;

    # Constraints
    subto R1: +120*x +210*y <= 15000;
    subto R2: +110*x +30*y <= 4000;
    subto R3: +x +y <= 75;

#### API

Use the lpsolve API call read_XLI to read a model and write_XLI to write a model. See also External Language Interfaces.

#### IDE

Also from within the IDE, this XLI can be used. However, some entries must be added in LpSolveIDE.ini (in the folder where the IDE is installed).

In the [XLI] section the following must be added:

    lib5=xli_ZIMPL

And a new section for the ZIMPL XLI must also be added:

    [xli_ZIMPL]
    extension=.zpl
    language=ZIMPL

Then make sure that the xli_ZIMPL.dll is available for the IDE. This must be done by placing this dll in the IDE folder or in the Windows system32 folder.

#### Example models

##### chvatal_diet.zpl

    # $Id: chvatal_diet.zpl,v 1.2 2003/10/02 08:20:12 bzfkocht Exp $
    #
    # From V. Chvatal: Linear Programming
    # Chapter 1, Page 3ff.
    #
    # A diet problem
    #
    set Food      := { "Oatmeal", "Chicken", "Eggs", "Milk", "Pie", "Pork" };
    set Nutrients := { "Energy", "Protein", "Calcium" };
    set Attr      := Nutrients + {"Servings", "Price"};

    param needed[Nutrients] := <"Energy"> 2000, <"Protein"> 55, <"Calcium"> 800;

    param data[Food * Attr] :=
               | "Servings", "Energy", "Protein", "Calcium", "Price" |
    |"Oatmeal" |         4 ,     110 ,        4 ,        2 ,      3  |
    |"Chicken" |         3 ,     205 ,       32 ,       12 ,     24  |
    |"Eggs"    |         2 ,     160 ,       13 ,       54 ,     13  |
    |"Milk"    |         8 ,     160 ,        8 ,      284 ,      9  |
    |"Pie"     |         2 ,     420 ,        4 ,       22 ,     20  |
    |"Pork"    |         2 ,     260 ,       14 ,       80 ,     19  |;
    #                          (kcal)        (g)        (mg)  (cents)

    var x[<f> in Food] integer >= 0 <= data[f, "Servings"];

    minimize cost: sum <f> in Food : data[f, "Price"] * x[f];

    subto need :
      forall <n> in Nutrients do
        sum <f> in Food : data[f, n] * x[f] >= needed[n];

##### model.lp

    /* model.lp */

    max: 143 x + 60 y;

    120 x + 210 y <= 15000;
    110 x + 30 y <= 4000;
    x + y <= 75;