Search code examples
minizinc

Output an absent optional enum in MiniZinc


How does on output an optional enum?

enum Foo = { A, B };
var opt Foo: foo;
output [ "foo: \(foo)" ];
solve satisfy;

fails with this output:

Compiling test.mzn
MiniZinc: flattening error: 
  function _toString_Foo is used in output, par version needed
Finished in 29msec

If I change Foo to be a set of int

set of int: Foo = 1..2;
var opt Foo: foo;
output [ "foo: \(foo)" ];
solve satisfy;

then it works

Compiling test.mzn
Running test.mzn
foo: <>
----------
Finished in 136msec

And the missing value is clearly not a problem here.

Even if I check if the solution is present, it still fails

set of int: Foo = 1..2;
var opt Foo: foo;
output [ "foo: " ++
     if (occurs(fix(foo))) then "present" else "absent" endif
                                          ];
solve satisfy;

That fails with

Compiling test.mzn
Running test.mzn
MiniZinc: evaluation error: undeclared identifier '_absent'
unknown file
Finished in 39msec

Actually, that even fails with a set of int.


Solution

  • UPDATE: The issue has been resolved on the develop branch of the MiniZinc compiler. In the next release, >2.1.6, it should be possible to use the optional parameters in the output.


    Because enumerations are represented as integers in the solver input, special mapping functions are inserted into the output model to ensure the correct output.

    Transforming the solver output into MiniZinc output is the task of the solns2out executable. This is done using an output model (.ozn).

    The error you are getting is because the function required to map the integers back into the enumeration is not found, this is a bug in the compiler. Only two days ago the _toString_ function for sets of enumerations was added to the development branch and it seems the version for optional types is still missing.

    I suggest you create an issue on GitHub and the issue will likely be resolved in the next MiniZinc release: https://github.com/MiniZinc/libminizinc/issues