The predicates described here operate on a data structure
FznState representing a FlatZinc program. The details of
FznState is reserved (subject to change). It 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 that is initialized with respect to FznStream.
fzn_load_file(+FznFile, -FznState)
FznFile is a FlatZinc file (extension defaults to .fzn).
FznState is a FlatZinc state that is initialized with respect to
FznFile. This predicate is just a wrapper around
fzn_load_stream/2
handling stream opening and closing.
Consider the following FlatZinc program for solving the 4 Queens problem
located in library('zinc/examples/queen4.fzn')
.
% queen4.fzn
int: n = 4; array[1 .. 4] of var 1 .. 4: q::output_array([ 1 .. 4 ]); 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[2] ], -1); 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[3] ], -2); 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[1], q[4] ], -3); 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[3] ], -1); 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[2], q[4] ], -2); constraint int_lin_ne([ 1, -1 ], [ q[3], q[4] ], 1); constraint int_ne(q[3], q[4]); constraint int_lin_ne([ 1, -1 ], [ q[3], q[4] ], -1); solve satisfy;
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 and output parts of the FlatZinc program represented by FznState to find and display an (optimal) solution. Fails if the constraints of the FlatZinc program are inconsistent. Generates the next solution upon backtracking.
fzn_output(+FznState)
Outputs the values of the variables in FznState that have been
annotated with output_var/0
or output_array/1
.
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).
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 and output parts of
queen4.fzn
, respectively. The following is written on the current
output stream:
q = array1d(1..4, [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:
q = array1d(1..4, [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:
bool
is translated into a Prolog integer:
false
is translated into 0
and true
is translated
into 1
.
int
is translated into a Prolog integer.
float
is translated into a Prolog float.
library(clpfd)
range
expression (see Syntax of Range Expressions).
var
is translated into a library(clpfd)
domain
variable (see CLPFD Interface).
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.
A possible use 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:
| ?- use_module(library(clfpd)). | ?- 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:
q = array1d(1..4, [2,4,1,3]); ---------- q = array1d(1..4, [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:
q = array1d(1..4, [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.
fzn_run_stream(+FznStream)
fzn_run_stream(+FznStream, +Options)
FznStream is a FlatZinc input stream and Options is a list of options; see Zinc Options. Performs the following steps:
fzn_load_stream/2
), initializing a
FlatZinc state.
fzn_post/1
).
fzn_solve/1
).
output_var/0
or output_array/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, if the whole search space have been explored, then ten consecutive equal signs are output on a separate line.
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; see see Zinc Options. This
predicate is just a wrapper around fzn_run_stream/[1,2]
handling
stream opening and closing.
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 of options; see see Zinc Options.
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), C#\=D, B#\=D, B#\=C, A#\=D, A#\=C, A#\=B, scalar_product([1,-1], [C,D], #\=, 1), scalar_product([1,-1], [C,D], #\=, -1), scalar_product([1,-1], [B,D], #\=, 2), scalar_product([1,-1], [B,D], #\=, -2), scalar_product([1,-1], [B,C], #\=, 1), scalar_product([1,-1], [B,C], #\=, -1), scalar_product([1,-1], [A,D], #\=, 3), scalar_product([1,-1], [A,D], #\=, -3), scalar_product([1,-1], [A,C], #\=, 2), scalar_product([1,-1], [A,C], #\=, -2), scalar_product([1,-1], [A,B], #\=, 1), scalar_product([1,-1], [A,B], #\=, -1).