10.38.2.1 Exported Predicates

The predicates described here operate on a data structure FznState representing a FlatZinc program and consisting of the following members:

This data structure can be constructed from a FlatZinc program by the predicates fzn_load_stream/2 and fzn_load_file/2 described next, or directly from a MiniZinc program (see MiniZinc).

fzn_load_stream(+FznStream, -FznState)
FznStream is a FlatZinc input stream. FznState is a FlatZinc state which is initialized with respect to FznStream.

Exceptions: Exceptions regarding errors in FznStream (see Zinc Errors).

fzn_load_file(+FznFile, -FznState)
FznFile is a FlatZinc file (extension defaults to .fzn). FznState is a FlatZinc state which is initialized with respect to FznFile. This predicate is just a wrapper around fzn_load_stream/2 handling stream opening and closing.

Exceptions:

Consider the following FlatZinc program for solving the 4 Queens problem located in library('zinc/examples/queen4.fzn'). (Note that FlatZinc programs are not intended to be written (or read) by humans, but rather to be automatically generated: one method to generate FlatZinc programs is described in MiniZinc.)

                               
% queen4.fzn
int: n = 4; array[1 .. 4] of var 1 .. 4: q; constraint int_lin_ne([ 1, -1 ], [ q[1], q[2] ], -1); constraint int_lin_ne([ 1, -1 ], [ q[1], q[2] ], 1); constraint int_ne(q[1], q[2]); constraint int_lin_ne([ 1, -1 ], [ q[1], q[3] ], -2); constraint int_lin_ne([ 1, -1 ], [ q[1], q[3] ], 2); constraint int_ne(q[1], q[3]); constraint int_lin_ne([ 1, -1 ], [ q[1], q[4] ], -3); constraint int_lin_ne([ 1, -1 ], [ q[1], q[4] ], 3); constraint int_ne(q[1], q[4]); constraint int_lin_ne([ 1, -1 ], [ q[2], q[3] ], -1); constraint int_lin_ne([ 1, -1 ], [ q[2], q[3] ], 1); constraint int_ne(q[2], q[3]); constraint int_lin_ne([ 1, -1 ], [ q[2], q[4] ], -2); constraint int_lin_ne([ 1, -1 ], [ q[2], q[4] ], 2); constraint int_ne(q[2], q[4]); constraint int_lin_ne([ 1, -1 ], [ q[3], q[4] ], -1); constraint int_lin_ne([ 1, -1 ], [ q[3], q[4] ], 1); constraint int_ne(q[3], q[4]); solve satisfy; output [ "A solution to the ", "4", " Queens problem: ", show(q), "\n"];

A FlatZinc state Queen4State representing the program above can be constructed by typing:

     | ?- fzn_load_file(library('zinc/examples/queen4'), Queen4State).

The predicates presented next are used to query an already initialized FlatZinc state.

fzn_post(+FznState)
Posts the constraints of the FlatZinc program represented by FznState. May fail if the constraints are inconsistent.
fzn_solve(+FznState)
Runs the solve part of the FlatZinc program represented by FznState to find an (optimal) solution. Fails if the constraints of the FlatZinc program are inconsistent. Generates the next solution upon backtracking.
fzn_output(+FznState)
Runs the output part of the FlatZinc program represented by FznState. The output is written on the current output stream.

Consider again the FlatZinc program queen4.fzn described above and the following goal at the Prolog top level:

     | ?- fzn_load_file(library('zinc/examples/queen4'), Queen4State),
          fzn_post(Queen4State),
          fzn_solve(Queen4State),
          fzn_output(Queen4State).

The first line initializes Queen4State with respect to queen4.fzn. The second and third line posts the constraints of queen4.fzn and runs the solve part of queen4.fzn, respectively. Finally, the fourth line runs the output part of queen4.fzn which means that the following is written on the current output stream:

     A solution to the 4 Queens problem: [2, 4, 1, 3]

Upon backtracking the solve and output parts of Queen4State are rerun, which means that the following is written on the current output stream:

     A solution to the 4 Queens problem: [3, 1, 4, 2]
fzn_identifier(+FznState, +Id, -Value)
FznState is a FlatZinc state initialized with respect to some FlatZinc program and Id is an identifier of the FlatZinc program. Unifies the FlatZinc value of Id with Value according to the following translation scheme:

Exceptions: An existence error if Id is not an identifier of FznState.

fzn_objective(+FznState, -Objective)
FznState is a FlatZinc state initialized with respect to some FlatZinc program. Unifies Objective with a domain variable representing the FlatZinc objective. Note that currently only a var int or a var bool is allowed in the FlatZinc objective.

Exceptions: An existence error if there is no objective in FznState.

A possible usage of fzn_identifier/3 is to post additional library(clpfd) constraints or to apply a Prolog labeling predicate on the FlatZinc variables. For example, given the 4 Queens problem in queen4.fzn described above, the following goal labels the variables to find all solutions:

     | ?- fzn_load_file(library('zinc/examples/queen4'), Queen4State),
          fzn_post(Queen4State),
          fzn_identifier(Queen4State, q, Q),
          findall(_, (labeling([], Q), fzn_output(Queen4State)), _).

Given this goal, the following is written on the current output stream:

     A solution to the 4 Queens problem: [2, 4, 1, 3]
     A solution to the 4 Queens problem: [3, 1, 4, 2]

To avoid symmetric solutions where the chess board is rotated 180 degrees, the following goal posts an additional symmetry breaking constraint on the first two queens:

     | ?- fzn_load_file(library('zinc/examples/queen4'), Queen4State),
          fzn_post(Queen4State),
          fzn_identifier(Queen4State, q, Q),
          Q = [Q1, Q2|_], Q1 #< Q2,
          findall(_, (labeling([], Q), fzn_output(Queen4State)), _).

Given this goal, the following is written on the current output stream:

     A solution to the 4 Queens problem: [2, 4, 1, 3]

Note that, now, only the first one of the previous two solutions is displayed.

The following two predicates can be used to run a FlatZinc program in one go. They both take as optional argument a list Options which can be used to change the default behavior of the execution. This list may contain zero or more of the following (currently, this is the only available option):

solutions(NumberOfSolutions)
where NumberOfSolutions must be an integer greater than zero or the atom all. Describes the number of solutions to search for, default is 1.
fzn_run_stream(+FznStream)
fzn_run_stream(+FznStream, +Options)
FznStream is a FlatZinc input stream and Options is a list of options as described above. Performs the following steps:
  1. Loads the FlatZinc program (fzn_load_stream/2), initializing a FlatZinc state.
  2. Posts the constraints of the FlatZinc program (fzn_post/1).
  3. Runs the solve part of the FlatZinc program (fzn_solve/1).
  4. Runs the output part of the FlatZinc program (fzn_output/1).

The two final steps are repeated until the number of solutions as specified in Options have been found or until no more solutions can be found. At this point one of the following is written on the current output stream:

No solution found
when no solution was found (satisfaction and optimization problems).
N solution(s) found
when N solutions was found (satisfaction problems).
Optimal solution found
when an optimal solution was found (optimization problems).

Exceptions:


fzn_run_file(+FznFile)
fzn_run_file(+FznFile, +Options)
FznFile is a FlatZinc program file (extension defaults to .fzn) and Options is a list of options as described above. This predicate is just a wrapper around fzn_run_stream/[1,2] handling stream opening and closing.

Exceptions:

The next predicate can be used to write the constraints of a FlatZinc program to a file, in the format of library(clpfd).

fzn_dump(+FznState, +File)
fzn_dump(+FznState, +Options, +File)
FznState is a FlatZinc state initialized with respect to some FlatZinc program and File is a writable file (extension defaults to .pl). Writes the constraints of FznState to File in the format of library(clpfd).

Options is a list containing zero or more of the following (currently, this is the only available option):

Exceptions: Exceptions related to the opening of File for writing.

Consider again the FlatZinc program queen4.fzn described above and the following goal at the Prolog top level:

     | ?- fzn_load_file(library('zinc/examples/queen4'), Queen4State),
          fzn_dump(Queen4State, [variables([q=Q])], queen4).

The file queen4.pl then contains the following:

                                  
queen4.pl
:- use_module(library(clpfd)). query([q=[A,B,C,D]]) :- domain([A,B,C,D], 1, 4), scalar_product([1,-1], [A,B], #\=, -1), scalar_product([1,-1], [A,B], #\=, 1), A#\=B, scalar_product([1,-1], [A,C], #\=, -2), scalar_product([1,-1], [A,C], #\=, 2), A#\=C, scalar_product([1,-1], [A,D], #\=, -3), scalar_product([1,-1], [A,D], #\=, 3), A#\=D, scalar_product([1,-1], [B,C], #\=, -1), scalar_product([1,-1], [B,C], #\=, 1), B#\=C, scalar_product([1,-1], [B,D], #\=, -2), scalar_product([1,-1], [B,D], #\=, 2), B#\=D, scalar_product([1,-1], [C,D], #\=, -1), scalar_product([1,-1], [C,D], #\=, 1), C#\=D.

Send feedback on this subject.