Skip to content

Commit

Permalink
Fix #1097:
Browse files Browse the repository at this point in the history
- the Bash and Bat files are replaced by a Python script
- with Nuitka, the Python script is turned into an executable, adapted to the OS
- Update MINIZINC.md (and Makefile) to reflect the changes
  • Loading branch information
cprudhom committed Jun 27, 2024
1 parent e7cb320 commit d9e67ef
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 366 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ msc: compet
@sed -i '' 's| "version": .*| "version" : "$(CURRENT_VERSION)",|' parsers/src/main/minizinc/choco.msc
@sed -i '' 's|SNAPSHOT|$(DATE)|g' parsers/src/main/minizinc/choco.msc
@sed -i '' 's| "mznlib": .*| "mznlib" : "$(ROOT_DIR)/parsers/src/main/minizinc/mzn_lib/",|' parsers/src/main/minizinc/choco.msc
@sed -i '' 's| "executable": .*| "executable" : "$(ROOT_DIR)/parsers/src/main/minizinc/fzn-choco",|' parsers/src/main/minizinc/choco.msc
@sed -i '' 's| "executable": .*| "executable" : "$(ROOT_DIR)/parsers/src/main/minizinc/fzn-choco.bin",|' parsers/src/main/minizinc/choco.msc
@sed -i '' 's|^[^ ]*CHOCO_JAR=.*|CHOCO_JAR=$(ROOT_DIR)/parsers/target/choco-parsers-$(CURRENT_VERSION)-light.jar|' parsers/src/main/minizinc/fzn-choco
@cp $(ROOT_DIR)/parsers/src/main/minizinc/choco.msc ~/.minizinc/solvers/choco-$(CURRENT_VERSION)-$(DATE).msc

Expand Down
143 changes: 74 additions & 69 deletions parsers/MINIZINC.md
Original file line number Diff line number Diff line change
@@ -1,83 +1,88 @@
MiniZinc Parser
===============

This is related to [MiniZinc and FlatZinc format](http://www.minizinc.org).
You can find here the instructions to parse and solve [MiniZinc](http://www.minizinc.org) files with Choco-solver.
The first thing to understand is that MiniZinc is a high-level constraint modeling language and
choco-solver is not able to parse MiniZinc files directly.
Actually, MiniZinc files must be converted into [FlatZinc](https://docs.minizinc.dev/en/stable/part_4_reference.html)
files before being parsed by Choco-solver.

There exists different ways to parse and solve MiniZinc files with Choco-solver.

### MiniZinc IDE

The first approach, that should be favoured, is to add Choco-solver as a [third-Party Solver in MiniZinc IDE](https://www.minizinc.org/doc-2.5.5/en/fzn-spec.html#solver-configuration-files).
A *solver configuration file* that contains some basic information is available, named [choco.msc](https://github.com/chocoteam/choco-solver/blob/master/parsers/src/main/minizinc/choco.msc).
With respect to MiniZinc specification, this file should be added in:
> the directory `$HOME/.minizinc/solvers` on Linux and macOS systems, and the Application Data directory on Windows systems.
> [Source](https://www.minizinc.org/doc-2.4.3/en/fzn-spec.html#solver-configuration-files)

The script referred to in this file, together with global constraints definition can be downloaded from [the MiniZinc repository](https://github.com/chocoteam/choco-solver/tree/master/parsers/src/main/minizinc) on GitHub.

1. Edit `choco.msc` to set the `"mznlib"` and `"executable"` fields.
The `"executable"` field should point to the script `fzn_choco` or `fzn-choco.exe` depending on your OS.
The `"mznlib"` field should point to the directory containing the global constraints definition, i.e. `mzn_lib` directory.
Full path are expected.
2. Copy `choco.msc` to `~/.minizinc/solvers/` directory on Linux and macOS systems (
`cp ./parsers/src/main/minizinc/choco.msc ~/.minizinc/solvers/`).
On Windows systems, the file must be placed in the Application Data directory.
3. Edit `./parsers/src/main/minizinc/fzn-choco` (or `./parsers/src/main/minizinc/fzn-choco.exe` for Windows users)
and set the `CHOCO_JAR` variable to the path of the Choco-solver jar file, i.e. `choco-parsers-4.10.15-light.jar`.


### Converting from MiniZinc to FlatZinc

If one wants to manually convert MiniZinc files into FlatZinc files parsable by Choco-solver.

The [`mzn_lib`](https://github.com/chocoteam/choco-solver/blob/master/parsers/src/main/minizinc/mzn_lib) directory lists the supported global constraints for Choco-solver.
It is needed as an argument of `minizinc`, a tool to convert MiniZinc files to FlatZinc files.

```bash
minizinc -c --solver org.minizinc.mzn-fzn -I "/path/to/mzn_lib" model.mzn -d data.dzn -o output.fzn
The recommended way is to use the MiniZinc IDE,
which is a graphical user interface that allows to write, parse and solve MiniZinc files.

## Pre-requisites

### Choco-solver jar file

Before starting, you need to download the Choco-solver jar file that contains the parser for FlatZinc files.
This jar file is available on the [Choco-solver repository](https://github.com/chocoteam/choco-solver/releases) on GitHub.
Or you can build it from the source code.
In that case, you need to get the jar file from the `parsers/target` directory.
Select the jar file that contains the `-light` suffix.

### Executable script
To parse and solve FlatZinc files, you need an executable script that calls the Choco-solver parser.
This script is available in the [`parsers/src/main/minizinc` directory](https://github.com/chocoteam/choco-solver/tree/master/parsers/src/main/minizinc)
of the Choco-solver repository on GitHub.
The entry point of this script is the `fzn-choco.py` file, which is a Python script that calls the Choco-solver parser.
Unfortunately, MiniZinc requires an executable script, so you need to create a shell script that calls the Python script.

Creating the executable script is quite straighforward with [Nuitka](https://nuitka.net/).

##### Building the executable script with Nuitka

First of all, you have to have a Python interpreter installed on your machine (version >=3.10).
Then, you can install Nuitka with the following command:
```bash
pip install nuitka
```

where `model.mzn` is the MiniZinc file describing the model,
`data.dzn` (optional) contains data to instantiate the MiniZinc file and
`output.fzn` is the output FlatZinc filename you want.

The `-I` argument defines global constraints provided by Choco-solver.

See MiniZinc documentation for more details on how to convert MiniZinc files into FlatZinc files.

### Parsing and solving a FlatZinc file

Then, there are two ways to parse and solve a FlatZinc file with Choco:

* ##### Java front-end
Once Nuitka is installed, you need to adapt the `fzn-choco.py` script to set the path to the Choco-solver jar file.
Set the `JAR_FILE` variable to the path of the Choco-solver jar file.

Then, you can build the executable script with the following command:
```bash
java -cp .:/path/to/choco-parsers-4.10.3-jar-with-dependencies.jar org.chocosolver.parser.flatzinc.ChocoFZN [<options>] [<file>]
```

Common __options__ are:
* ```-a``` : This causes the solver to search for, and output all solutions in case of satisfaction problems. For optimization problems, the solver search for an optimal solution and outputs all intermediate solutions. When this option is not given the solver should search for and output only the first solution (for satisfaction problems) or the best known one (for optimization problems).
* ```-f```: When invoked with this option the solver ignores any specified search strategy.
* ```-p <n>```: When invoked with this option the solver is free to use multiple threads and/or cores during search. The argument <n> specifies the number of cores that are available.
* ```-tl <n>```: Limit the resolution time of each problem instance to <n> ms.
* other Choco-specific options are available

* ##### In a terminal (shell for Linux based OS)

```bash
sh ./parser/src/main/minizinc/fzn-choco -jar /path/to/choco-parsers-4.10.3-jar-with-dependencies.jar [<options>] [<file>]
```

Calling the shell with `-h` option will print the help message.
python -m nuitka fzn-choco.py
```

This command will create an executable script in the same directory as the Python script.
In the following, we will refer to this script as `fzn-choco` (without the `.py` extension).

**Important**:
For some reason, the executable script may be slower than the Python script.

## MiniZinc IDE
Now, Choco-solver can be added as a [third-Party Solver in MiniZinc IDE](https://docs.minizinc.dev/en/stable/fzn-spec.html#solver-configuration-files)
in MiniZincIDE.
This step requires to create a *solver configuration file* (with _.msc_ extension) that contains some basic information.
With respect to [MiniZinc specification](https://www.minizinc.org/doc-2.4.3/en/fzn-spec.html#solver-configuration-files),
this file can be added in:
> the directory `$HOME/.minizinc/solvers` on Linux and macOS systems, and the Application Data directory on Windows systems.
### Important
Before moving the file to the correct directory, it must be edited to set the correct paths.
There are two fields in the _.msc_ file that must be set:
- `"mznlib"`: the absolute path to the directory containing the global constraints definition, i.e. `mzn_lib` directory.
- `"executable"`: the absolute path to the executable script `fzn_choco` or `fzn-choco.exe` depending on your OS.

To avoid declaring the `-jar` option, you can export it once before calling the shell:
The script referred to in this file (_choco.msc)_, together with global constraints definition can be downloaded from
[the MiniZinc repository](https://github.com/chocoteam/choco-solver/tree/master/parsers/src/main/minizinc) on GitHub.


`PARSER_JAR=/path/to/choco-parsers-4.10.3-jar-with-dependencies.jar`

`sh ./parser/src/main/minizinc/fzn-choco [<options>] [<file>]`
1. Edit `choco.msc` to set the `"mznlib"` and `"executable"` fields.
1. The `"executable"` field should be set to the path of the executable script `fzn-choco`.
You must set the full path to the script, including the extension (like `.exe` or `.bin`).
2. The `"mznlib"` field should be set to the absolute path of the directory containing the global constraints definition,
i.e. `mzn_lib` directory.
2. Copy `choco.msc` to the directory recommended by MiniZinc (please refer to the MiniZinc documentation).
3. Restart MiniZinc IDE.


### Dockerfile

Some Choco-solver Docker images for the MiniZinc Challenge are available on [hub.docker.com/](https://hub.docker.com/repository/docker/chocoteam/choco-solver-mzn/general).
Note that the `fzn-choco` script can be used in a Docker container.
A `Dockerfile` is available in the `parsers/src/main/minizinc` directory of the Choco-solver repository on GitHub.
Some Choco-solver Docker images for the MiniZinc Challenge are available on
[hub.docker.com/](https://hub.docker.com/repository/docker/chocoteam/choco-solver-mzn/general).
28 changes: 21 additions & 7 deletions parsers/src/main/minizinc/docker/Dockerfile.dms
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,40 @@
# 1. Stage: Setup of Choco in the MiniZinc Challenge docker image

# Using the MiniZinc Challenge docker image
FROM minizinc/mznc2023:latest
FROM minizinc/mznc2024:latest as build

# Install Java 17 @
RUN apt-get update && \
apt-get install -y \
openjdk-17-jre-headless vim
vim python3.11 python3-pip patchelf && \
pip install nuitka

# The following command is used to disable caching for the ADD command and the next ones
ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
# Copy Choco's files from the local repository
COPY ./parsers/target/choco-parsers-*-light.jar /choco/choco.jar
COPY ./parsers/src/main/minizinc/fzn-choco /choco/fzn-choco
COPY ./parsers/src/main/minizinc/fzn-choco.py /choco/fzn-choco.py
COPY ./parsers/src/main/minizinc/choco.msc /choco/choco.msc
COPY ./parsers/src/main/minizinc/mzn_lib/* /choco/mzn-lib/

# Update files
RUN sed -i 's&CHOCO_JAR=.*&CHOCO_JAR=/choco/choco.jar&g' /choco/fzn-choco && \
RUN sed -i 's&JAR_FILE=.*&JAR_FILE="/choco/choco.jar"&g' /choco/fzn-choco.py && \
sed -i 's&"mznlib".*&"mznlib":"/choco/mzn-lib/",&g' /choco/choco.msc && \
sed -i 's&"executable".*&"executable":"/choco/fzn-choco",&g' /choco/choco.msc
sed -i 's&"executable".*&"executable":"/choco/fzn-choco.bin",&g' /choco/choco.msc && \
cd /choco/ && \
# Now compile the python file to a binary file called fzn-choco.bin \
python3 -m nuitka /choco/fzn-choco.py && \
cd /minizinc/

ENV MZN_SOLVER_PATH=/choco:${MZN_SOLVER_PATH}
# 2. Stage: Move the Choco executable and its MiniZinc library to the MiniZinc Challenge docker image
FROM minizinc/mznc2024:latest as main

RUN echo '{"tagDefaults": [["", "org.choco.choco"]]}' > $HOME/.minizinc/Preferences.json
RUN apt-get update && \
apt-get install -y \
#default-jre-headless
openjdk-21-jre-headless vim

COPY --from=build /choco/ /choco/

RUN echo '{"mzn_solver_path": ["/choco/"],' > $HOME/.minizinc/Preferences.json && \
echo '"tagDefaults": [["", "org.choco.choco"]]}' >> $HOME/.minizinc/Preferences.json
153 changes: 0 additions & 153 deletions parsers/src/main/minizinc/fzn-choco

This file was deleted.

Loading

0 comments on commit d9e67ef

Please sign in to comment.