this repo has no description
1.. _ch-fzn-interfacing:
2
3Interfacing Solvers to Flatzinc
4===============================
5
6This document describes the interface between the MiniZinc system and FlatZinc solvers.
7
8.. _ch-fzn-spec:
9
10Specification of FlatZinc
11-------------------------
12
13This document is the specification of the FlatZinc modelling language.
14It also includes a definition of the standard command line options a FlatZinc solver should support
15in order to work with the ``minizinc`` driver program (and the MiniZinc IDE).
16
17FlatZinc is the target constraint modelling language into which MiniZinc
18models are translated.
19It is a very simple solver independent problem specification language,
20requiring minimal implementation effort to support.
21
22Throughout this document: :math:`r_1`, :math:`r_2` denote float literals; :math:`x_1, x_2, \dots, x_k, i, j, k` denote int literals; :math:`y_1, y_2, \dots, y_k, y_i` denote literal array elements.
23
24Comments
25~~~~~~~~
26
27Comments start with a percent sign ``%`` and extend to the end of the line. Comments can appear anywhere in a model.
28
29Types
30~~~~~
31
32There are three varieties of types in FlatZinc.
33
34- *Parameter* types apply to fixed values that are specified directly in the model.
35- *Variable* types apply to values computed by the solver during search. Every parameter type has a corresponding variable type; the variable type being distinguished by a ``var`` keyword.
36- *Annotations* and *strings*: annotations can appear on variable declarations, constraints, and on the solve goal. They provide information about how a variable or constraint should be treated by the solver (e.g., whether a variable should be output as part of the result or whether a particular constraint should implemented using domain consistency). Strings may appear as arguments to annotations, but nowhere else.
37
38Parameter types
39+++++++++++++++
40
41Parameters are fixed quantities explicitly specified in the model
42(see rule :mzndef:`<par-type>` in :numref:`ch-fzn-syntax`).
43
44============================================ ===========================
45Type Values
46============================================ ===========================
47``bool`` ``true`` or ``false``
48``float`` float
49``int`` int
50``set of int`` subset of int
51``array [1..`` :math:`n` ``] of bool`` array of bools
52``array [1..`` :math:`n` ``] of float`` array of floats
53``array [1..`` :math:`n` ``] of int`` array of ints
54``array [1..`` :math:`n` ``] of set of int`` array of sets of ints
55============================================ ===========================
56
57A parameter may be used where a variable is expected, but not vice versa.
58
59In predicate declarations the following additional parameter types are allowed.
60
61=================================================================================== ===========================
62Type Values
63=================================================================================== ===========================
64:math:`r_a` ``..`` :math:`r_b` bounded float
65:math:`x_a` ``..`` :math:`x_b` int in range
66``{`` :math:`x_a, x_b, \ldots, x_k` ``}`` int in set
67``set of`` :math:`x_a` ``..`` :math:`x_b` subset of int range
68``set of`` ``{`` :math:`x_a, x_b, \ldots, x_k` ``}`` subset of int set
69``array [1..`` :math:`n` ``] of`` :math:`r_a` ``..`` :math:`r_b` array of floats in range
70``array [1..`` :math:`n` ``] of`` :math:`x_a` ``..`` :math:`x_b` array of ints in range
71``array [1..`` :math:`n` ``] of set of`` :math:`x_a` ``..`` :math:`x_b` array of sets of ints in range
72``array [1..`` :math:`n` ``] of set of`` ``{`` :math:`x_a, x_b, \ldots, x_k` ``}`` array of subsets of set
73=================================================================================== ===========================
74
75A range :math:`x_a` ``..`` :math:`x_b` denotes a closed interval
76:math:`\{x | x_a \leq x \leq x_b\}` (same for float ranges).
77
78An array type appearing in a predicate declaration may use just
79``int`` instead of ``1..`` :math:`n` for the array index range
80in cases where the array argument can be of any length.
81
82Variable types
83++++++++++++++
84
85Variables are quantities decided by the solver
86(see rules :mzndef:`<basic-var-type>` and :mzndef:`<array-var-type>` in :numref:`ch-fzn-syntax`).
87
88+-----------------------------------------------------------------------------------+
89| Variable type |
90+===================================================================================+
91|``var bool`` |
92+-----------------------------------------------------------------------------------+
93|``var float`` |
94+-----------------------------------------------------------------------------------+
95|``var`` :math:`r_a` ``..`` :math:`r_b` |
96+-----------------------------------------------------------------------------------+
97|``var int`` |
98+-----------------------------------------------------------------------------------+
99|``var`` :math:`x_a` ``..`` :math:`x_b` |
100+-----------------------------------------------------------------------------------+
101|``var`` ``{`` :math:`x_a, x_b, \ldots, x_k` ``}`` |
102+-----------------------------------------------------------------------------------+
103|``var set of`` :math:`x_a` ``..`` :math:`x_b` |
104+-----------------------------------------------------------------------------------+
105|``var set of {`` :math:`x_a, x_b, \ldots, x_k` ``}`` |
106+-----------------------------------------------------------------------------------+
107|``array [1..`` :math:`n` ``] of var bool`` |
108+-----------------------------------------------------------------------------------+
109|``array [1..`` :math:`n` ``] of var float`` |
110+-----------------------------------------------------------------------------------+
111|``array [1..`` :math:`n` ``] of var`` :math:`r_a` ``..`` :math:`r_b` |
112+-----------------------------------------------------------------------------------+
113|``array [1..`` :math:`n` ``] of var int`` |
114+-----------------------------------------------------------------------------------+
115|``array [1..`` :math:`n` ``] of var`` :math:`x_a` ``..`` :math:`x_b` |
116+-----------------------------------------------------------------------------------+
117|``array [1..`` :math:`n` ``] of var set of`` :math:`x_a` ``..`` :math:`x_b` |
118+-----------------------------------------------------------------------------------+
119|``array [1..`` :math:`n` ``] of var set of {`` :math:`x_a, x_b, \ldots, x_k` ``}`` |
120+-----------------------------------------------------------------------------------+
121
122In predicate declarations the following additional variable types are allowed.
123
124+-----------------------------------------------------------------------------------+
125| Variable type |
126+===================================================================================+
127|``var set of int`` |
128+-----------------------------------------------------------------------------------+
129|``array [1..`` :math:`n` ``] of var set of int`` |
130+-----------------------------------------------------------------------------------+
131
132An array type appearing in a predicate declaration may use just
133``int`` instead of ``1..`` :math:`n` for the array index range
134in cases where the array argument can be of any length.
135
136The string type
137+++++++++++++++
138
139String literals and literal arrays of string literals can appear as
140annotation arguments, but not elsewhere.
141Strings have the same syntax as in C programs (namely, they are
142delimited by double quotes and the backslash character is used for
143escape sequences).
144
145Examples:
146
147.. code-block:: minizinc
148
149 "" % The empty string.
150 "Hello."
151 "Hello,\nWorld\t\"quoted!\"" % A string with an embedded newline, tab and quotes.
152
153Values and expressions
154~~~~~~~~~~~~~~~~~~~~~~
155
156(See rule :mzndef:`<expr>` in :numref:`ch-fzn-syntax`)
157
158Examples of literal values:
159
160
161Type Literals
162``bool`` ``true``, ``false``
163``float`` ``2.718``, ``-1.0``, ``3.0e8``
164``int`` ``-42``, ``0``, ``69``
165``set of int`` ``{}``, ``{2, 3, 5}``, ``1..10``
166``arrays`` ``[]``, ``[`` :math:`y_a, \ldots, y_k` ``]``
167
168where each array element :math:`y_i` is either: a non-array literal, or the
169name of a non-array parameter or variable, ``v``. For example:
170
171
172.. code-block:: minizinc
173
174 [1, 2, 3] % Just literals
175 [x, y, z] % x, y, and z are variables or parameters.
176 [x, 3] % Mix of identifiers and literals
177
178:numref:`ch-fzn-syntax` gives the regular expressions specifying the
179syntax for float and int literals.
180
181FlatZinc models
182~~~~~~~~~~~~~~~
183
184A FlatZinc model consists of:
185
186#. zero or more external predicate declarations (i.e., a non-standard predicate that is supported directly by the target solver);
187#. zero or more parameter declarations;
188#. zero or more variable declarations;
189#. zero or more constraints;
190#. a solve goal
191
192in that order.
193
194FlatZinc uses the UTF-8 character set. Non-ASCII characters can only appear in string literals.
195
196FlatZinc syntax is case sensitive (``foo`` and ``Foo`` are different
197names).
198Identifiers start with a letter (``[A-Za-z]``) and are followed by
199any sequence of letters, digits, or underscores (``[A-Za-z0-9_]``).
200Additionally, identifiers of variable or parameter names may start with an underscore.
201Identifiers that correspond to the names of predicates, predicate parameters
202and annotations cannot have leading underscores.
203
204The following keywords are reserved and cannot be used as identifiers:
205``annotation``,
206``any``,
207``array``,
208``bool``,
209``case``,
210``constraint``,
211``diff``,
212``div``,
213``else``,
214``elseif``,
215``endif``,
216``enum``,
217``false``,
218``float``,
219``function``,
220``if``,
221``in``,
222``include``,
223``int``,
224``intersect``,
225``let``,
226``list``,
227``maximize``,
228``minimize``,
229``mod``,
230``not``,
231``of``,
232``satisfy``,
233``subset``,
234``superset``,
235``output``,
236``par``,
237``predicate``,
238``record``,
239``set``,
240``solve``,
241``string``,
242``symdiff``,
243``test``,
244``then``,
245``true``,
246``tuple``,
247``union``,
248``type``,
249``var``,
250``where``,
251``xor``.
252Note that some of these keywords are not used in FlatZinc.
253They are reserved because they are keywords in Zinc and MiniZinc.
254
255FlatZinc syntax is insensitive to whitespace.
256
257Predicate declarations
258~~~~~~~~~~~~~~~~~~~~~~
259
260(See rule :mzndef:`<predicate-item>` in :numref:`ch-fzn-syntax`)
261
262Predicates used in the model that are not standard FlatZinc must be
263declared at the top of a FlatZinc model, before any other lexical items.
264Predicate declarations take the form
265
266.. literalinclude:: fzn-grammar.mzn
267 :language: minizincdef
268 :start-after: % Predicate items
269 :end-before: %
270
271Annotations are not permitted anywhere in predicate declarations.
272
273It is illegal to supply more than one predicate declaration for a given
274:mzndef:`<identifier>`.
275
276Examples:
277
278.. code-block:: minizinc
279
280 % m is the median value of {x, y, z}.
281 %
282 predicate median_of_3(var int: x, var int: y, var int: z, var int: m);
283
284 % all_different([x1, .., xn]) iff
285 % for all i, j in 1..n: xi != xj.
286 %
287 predicate all_different(array [int] of var int: xs);
288
289 % exactly_one([x1, .., xn]) iff
290 % there exists an i in 1..n: xi = true
291 % and for all j in 1..n: j != i -> xj = false.
292 %
293 predicate exactly_one(array [int] of var bool: xs);
294
295
296Parameter declarations
297~~~~~~~~~~~~~~~~~~~~~~
298
299(See rule ``param_decl`` in :numref:`ch-fzn-syntax`)
300
301Parameters have fixed values and must be assigned values:
302
303.. literalinclude:: fzn-grammar.mzn
304 :language: minizincdef
305 :start-after: % Parameter declarations
306 :end-before: %
307
308where :mzndef:`<par-type>` is a parameter type, :mzndef:`<var-par-identifier>` is an identifier,
309and :mzndef:`<par-expr>` is a literal value (either a basic integer, float or bool literal, or a set or array of such literals).
310
311Annotations are not permitted anywhere in parameter declarations.
312
313Examples:
314
315.. code-block:: minizinc
316
317 float: pi = 3.141;
318 array [1..7] of int: fib = [1, 1, 2, 3, 5, 8, 13];
319 bool: beer_is_good = true;
320
321Variable declarations
322~~~~~~~~~~~~~~~~~~~~~
323
324(See rule ``var_decl`` in :numref:`ch-fzn-syntax`)
325
326Variables have variable types and can be declared with optional assignments.
327The assignment can fix a variable to a literal value, or create an alias to another
328variable. Arrays of variables always have an assignment, defining them in terms of an array literal
329that can contain identifiers of variables or constant literals.
330Variables may be declared with zero or more annotations.
331
332.. literalinclude:: fzn-grammar.mzn
333 :language: minizincdef
334 :start-after: % Variable declarations
335 :end-before: %
336
337where :mzndef:`<basic-var-type>` and :mzndef:`<array-var-type>` are variable types, :mzndef:`<var-par-identifier>` is an identifier,
338:mzndef:`<annotations>` is a (possibly empty) set of annotations, :mzndef:`<basic-expr>` is an identifier or a literal, and :mzndef:`<array-literal>` is a literal array
339value.
340
341Examples:
342
343.. code-block:: minizinc
344
345 var 0..9: digit;
346 var bool: b;
347 var set of 1..3: s;
348 var 0.0..1.0: x;
349 var int: y :: mip; % 'mip' annotation: y should be a MIP variable.
350 array [1..3] of var 1..10: b = [y, 3, digit];
351
352
353Constraints
354~~~~~~~~~~~
355
356(See rule :mzndef:`<constraint-item>` in :numref:`ch-fzn-syntax`)
357
358Constraints take the following form and may include zero or more annotations:
359
360
361.. literalinclude:: fzn-grammar.mzn
362 :language: minizincdef
363 :start-after: % Constraint items
364 :end-before: %
365
366The arguments expressions (:mzndef:`<expr>`) can be literal values or identifiers.
367
368Examples:
369
370.. code-block:: minizinc
371
372 constraint int_le(0, x); % 0 <= x
373 constraint int_lt(x, y); % x < y
374 constraint int_le(y, 10); % y <= 10
375 % 'domain': use domain consistency for this constraint:
376 % 2x + 3y = 10
377 constraint int_lin_eq([2, 3], [x, y], 10) :: domain;
378
379Solve item
380~~~~~~~~~~
381
382(See rule :mzndef:`<solve-item>` in :numref:`ch-fzn-syntax`)
383
384A model finishes with a solve item, taking one of the following forms:
385
386.. literalinclude:: fzn-grammar.mzn
387 :language: minizincdef
388 :start-after: % Solve item
389 :end-before: %
390
391The first alternative searches for any satisfying assignment, the second one searches for an assignment minimizing the given expression, and the third one for an assignment maximizing the expression. The :mzndef:`<basic-expr>` can be either a variable identifier or a literal value (if the objective function is constant).
392
393A solution consists of a complete assignment where all variables in the
394model have been given a fixed value.
395
396Examples:
397
398
399.. code-block:: minizinc
400
401 solve satisfy; % Find any solution using the default strategy.
402
403 solve minimize w; % Find a solution minimizing w, using the default strategy.
404
405 % First label the variables in xs in the order x[1], x[2], ...
406 % trying values in ascending order.
407 solve :: int_search(xs, input_order, indomain_min, complete)
408 satisfy; % Find any solution.
409
410 % First use first-fail on these variables, splitting domains
411 % at each choice point.
412 solve :: int_search([x, y, z], first_fail, indomain_split, complete)
413 maximize x; % Find a solution maximizing x.
414
415Annotations
416~~~~~~~~~~~
417
418Annotations are optional suggestions to the solver concerning how
419individual variables and constraints should be handled (e.g., a
420particular solver may have multiple representations for int variables)
421and how search should proceed.
422An implementation is free to ignore any annotations it does not
423recognise, although it should print a warning on the standard error
424stream if it does so.
425Annotations are unordered and idempotent: annotations can be reordered
426and duplicates can be removed without changing the meaning of the
427annotations.
428
429
430An annotation is prefixed by ``::``, and either just an identifier or an expression that looks like a predicate call:
431
432.. literalinclude:: fzn-grammar.mzn
433 :language: minizincdef
434 :start-after: % Annotations
435 :end-before: %
436
437The arguments of the second alternative can be any expression or other annotations (without the leading ``::``).
438
439Search annotations
440++++++++++++++++++
441
442While an implementation is free to ignore any or all annotations in a
443model, it is recommended that implementations at least recognise the
444following standard annotations for solve items.
445
446.. code-block:: minizincdef
447
448 seq_search([<searchannotation>, ...])
449
450allows more than one search annotation to be specified in a particular
451order (otherwise annotations can be handled in any order).
452
453A :mzndef:`<searchannotation>` is one of the following:
454
455.. code-block:: minizincdef
456
457 int_search(<vars>, <varchoiceannotation>, <assignmentannotation>, <strategyannotation>)
458
459 bool_search(<vars>, <varchoiceannotation>, <assignmentannotation>, <strategyannotation>)
460
461 set_search(<vars>, <varchoiceannotation>, <assignmentannotation>, <strategyannotation>)
462
463where :mzndef:`<vars>` is the identifier of an array variable or an array literal specifying
464the variables to be assigned (ints, bools, or sets respectively). Note that these arrays may contain literal values.
465
466:mzndef:`<varchoiceannotation>` specifies how the next variable to be assigned is
467chosen at each choice point.
468Possible choices are as follows (it is recommended that implementations
469support the starred options):
470
471+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
472| ``input_order`` | :math:`\star` | Choose variables in the order they appear in :mzndef:`vars`. |
473+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
474| ``first_fail`` | :math:`\star` | Choose the variable with the smallest domain. |
475+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
476| ``anti_first_fail`` | | Choose the variable with the largest domain. |
477+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
478| ``smallest`` | | Choose the variable with the smallest value in its domain. |
479+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
480| ``largest`` | | Choose the variable with the largest value in its domain. |
481+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
482| ``occurrence`` | | Choose the variable with the largest number of attached constraints. |
483+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
484| ``most_constrained`` | | Choose the variable with the smallest domain, breaking ties using the number of constraints. |
485+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
486| ``max_regret`` | | Choose the variable with the largest difference between the two smallest values in its domain. |
487+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
488| ``dom_w_deg`` | | Choose the variable with the smallest value of domain size divided by weighted degree, |
489| | | where the weighted degree is the number of times the variables been in a constraint which failed |
490+-----------------------+---------------+------------------------------------------------------------------------------------------------------+
491
492:mzndef:`<assignmentannotation>` specifies how the chosen variable should be
493constrained.
494Possible choices are as follows (it is recommended that implementations
495support at least the starred options):
496
497+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
498| ``indomain_min`` | :math:`\star` | Assign the smallest value in the variable's domain. |
499+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
500| ``indomain_max`` | :math:`\star` | Assign the largest value in the variable's domain. |
501+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
502| ``indomain_middle`` | | Assign the value in the variable's domain closest to the mean of its current bounds. |
503+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
504| ``indomain_median`` | | Assign the middle value in the variable's domain. |
505+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
506| ``indomain`` | | Nondeterministically assign values to the variable in ascending order. |
507+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
508| ``indomain_random`` | | Assign a random value from the variable's domain. |
509+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
510| ``indomain_split`` | | Bisect the variable's domain, excluding the upper half first. |
511+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
512| ``indomain_reverse_split``| | Bisect the variable's domain, excluding the lower half first. |
513+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
514| ``indomain_interval`` | | If the variable's domain consists of several contiguous intervals, |
515| | | reduce the domain to the first interval. Otherwise just split the variable's domain. |
516+---------------------------+---------------+------------------------------------------------------------------------------------------------------+
517
518Of course, not all assignment strategies make sense for all search
519annotations (e.g., ``bool_search`` and ``indomain_split``).
520
521Finally, :mzndef:`<strategyannotation>` specifies a search strategy;
522implementations should at least support ``complete`` (i.e., exhaustive
523search).
524
525Output annotations
526++++++++++++++++++
527
528Model output is specified through variable annotations.
529Non-array output variables are annotated with
530``output_var``.
531Array output variables are annotated with
532``output_array([`` :math:`x_1` ``..`` :math:`x_2` ``, ... ])``
533where :math:`x_1` ``..`` :math:`x_2` ``, ...`` are the index set ranges of the
534original MiniZinc array (which
535may have had multiple dimensions and/or index sets that do not start at
5361). See :numref:`ch-fzn-output` for details on the output format.
537
538Variable definition annotations
539+++++++++++++++++++++++++++++++
540
541To support solvers capable of exploiting functional relationships, a
542variable defined as a function of other variables may be annotated thus:
543
544.. code-block:: minizinc
545
546 var int: x :: is_defined_var;
547
548 ...
549
550 constraint int_plus(y, z, x) :: defines_var(x);
551
552(The ``defines_var`` annotation should appear on exactly one
553constraint.)
554This allows a solver to represent ``x`` internally as a representation
555of ``y+z`` rather than as a separate constrained variable.
556The ``is_defined_var`` annotation on the declaration of ``x``
557provides "early warning" to the solver that such an option is
558available.
559
560Intermediate variables
561++++++++++++++++++++++
562
563Intermediate variables introduced during conversion of a MiniZinc
564model to FlatZinc may be annotated thus:
565
566.. code-block:: minizinc
567
568 var int: X_INTRODUCED_3 :: var_is_introduced;
569
570This information is potentially useful to the solver's search strategy.
571
572Constraint annotations
573++++++++++++++++++++++
574
575Annotations can be placed on constraints advising the solver how the
576constraint should be implemented.
577Here are some constraint annotations supported by some solvers:
578
579
580+---------------------------+----------------------------------------------------------------------------+
581| ``bounds`` or ``boundsZ`` | Use integer bounds propagation. |
582+---------------------------+----------------------------------------------------------------------------+
583| ``boundsR`` | Use real bounds propagation. |
584+---------------------------+----------------------------------------------------------------------------+
585| ``boundsD`` | A tighter version of ``boundsZ`` where support for the bounds must exist. |
586+---------------------------+----------------------------------------------------------------------------+
587| ``domain`` | Use domain propagation. |
588+---------------------------+----------------------------------------------------------------------------+
589|``priority(k)`` | where ``k`` is an integer constant indicating propagator priority. |
590+---------------------------+----------------------------------------------------------------------------+
591
592.. _ch-fzn-output:
593
594Output
595------
596
597An implementation can produce three types of output: solutions, statistics, and errors.
598
599Solution output
600~~~~~~~~~~~~~~~
601
602An implementation must output values for all and only the variables
603annotated with ``output_var`` or ``output_array`` (output
604annotations must not appear on parameters). Output must be printed to
605the standard output stream.
606
607For example:
608
609.. code-block:: minizinc
610
611 var 1..10: x :: output_var;
612 var 1..10: y; % y is not output.
613 % Output zs as a "flat" representation of a 2D array:
614 array [1..4] of var int: zs :: output_array([1..2, 1..2]);
615
616All non-error output must be sent to the standard output stream.
617
618Output must take the following form:
619
620.. code-block:: minizincdef
621
622 <var-par-identifier> = <basic-literal-expr> ;
623
624or, for array variables,
625
626.. code-block:: minizincdef
627
628 <var-par-identifier> = array<N>d(<a>..<b>, ..., [<y1>, <y2>, ... <yk>]);
629
630where :mzndef:`<N>` is the number of index sets specified in the
631corresponding :mzndef:`output_array` annotation,
632:mzndef:`<a>..<b>, ...` are the index set ranges,
633and :mzndef:`<y1>, <y2>, ... <yk>` are literals of the element type.
634
635Using this format, the output of a FlatZinc model solution is
636suitable for input to a MiniZinc model as a data file (this is why
637parameters are not included in the output).
638
639Implementations must ensure that *all* model variables (not
640just the output variables) have satisfying assignments before printing a
641solution.
642
643The output for a solution must be terminated with ten consecutive
644minus signs on a separate line: ``----------``.
645
646Multiple solutions may be output, one after the other, as search
647proceeds. How many solutions should be output depends on the mode the solver is run in as controlled by the ``-a`` command line flag (see :numref:`fzn-cmdline-options`).
648
649If at least one solution has been found and search then terminates
650having explored the whole search space, then ten
651consecutive equals signs should be printed on a separate line:
652``==========``.
653
654If no solutions have been found and search terminates having explored
655the whole search space, then ``=====UNSATISFIABLE=====`` should be
656printed on a separate line.
657
658If the objective of an optimization problem is unbounded, then
659``=====UNBOUNDED=====`` should be printed on a separate line.
660
661If no solutions have been found and search terminates having
662*not* explored the whole search space, then
663``=====UNKNOWN=====`` should be printed on a separate line.
664
665Implementations may output further information about the solution(s),
666or lack thereof, in the form of FlatZinc comments.
667
668Examples:
669
670Asking for a single solution to this model:
671
672.. code-block:: minizinc
673
674 var 1..3: x :: output_var;
675 solve satisfy
676
677might produce this output:
678
679.. code-block:: minizinc
680
681 x = 1;
682 ----------
683
684Asking for all solutions to this model:
685
686.. code-block:: minizinc
687
688 array [1..2] of var 1..3: xs :: output_array([1..2]);
689 constraint int_lt(xs[1], xs[2]); % x[1] < x[2].
690 solve satisfy
691
692might produce this output:
693
694.. code-block:: minizinc
695
696 xs = array1d(1..2, [1, 2]);
697 ----------
698 xs = array1d(1..2, [1, 3]);
699 ----------
700 xs = array1d(1..2, [2, 3]);
701 ----------
702 ==========
703
704
705Asking for a single solution to this model:
706
707.. code-block:: minizinc
708
709 var 1..10: x :: output_var;
710 solve maximize x;
711
712should produce this output:
713
714.. code-block:: minizinc
715
716 x = 10;
717 ----------
718 ==========
719
720The row of equals signs indicates that a complete search was performed
721and that the last result printed is the optimal solution.
722
723Running a solver on this model with some termination condition (such as a very short time-out):
724
725.. code-block:: minizinc
726
727 var 1..10: x :: output_var;
728 solve maximize x;
729
730might produce this output:
731
732.. code-block:: minizinc
733
734 x = 1;
735 ----------
736 x = 2;
737 ----------
738 x = 3;
739 ----------
740
741Because the output does not finish with ``==========``, search did not
742finish, hence these results must be interpreted as approximate solutions
743to the optimization problem.
744
745Asking for a solution to this model:
746
747.. code-block:: minizinc
748
749 var 1..3: x :: output_var;
750 var 4..6: y :: output_var;
751 constraint int_lt(y, x); % y < x.
752 solve satisfy;
753
754should produce this output:
755
756.. code-block:: minizinc
757
758 =====UNSATISFIABLE=====
759
760indicating that a complete search was performed and no solutions were
761found (i.e., the problem is unsatisfiable).
762
763Statistics output
764~~~~~~~~~~~~~~~~~
765
766FlatZinc solvers can output statistics in a standard format so that it can be read by scripts,
767for example, in order to run experiments and automatically aggregate the results.
768Statistics should be printed to the standard output stream in the form of FlatZinc comments that follow a specific format.
769Statistics can be output at any time during the solving, i.e., before the first solution, between solutions,
770and after the search has finished. Statistics output corresponding to a solution should be the last one
771before its '----------' separator.
772
773Each value should be output on a line of its own in the following format:
774
775.. code-block:: minizincdef
776
777 %%%mzn-stat: <name>=<value>
778
779Each block of statistics is terminated by a line of its own with the following format:
780
781.. code-block:: minizincdef
782
783 %%%mzn-stat-end
784
785**Example**
786
787.. code-block:: minizincdef
788
789 %%%mzn-stat: objective=1e+308
790 %%%mzn-stat: objectiveBound=0
791 %%%mzn-stat: nodes=0
792 %%%mzn-stat: solveTime=2.3567
793 %%%mzn-stat-end
794
795 (no feasible solution found yet but something can be printed...)
796
797 %%%mzn-stat: objective=12345
798 %%%mzn-stat: objectiveBound=122
799 %%%mzn-stat: nodes=35
800 %%%mzn-stat: solveTime=78.5799
801 %%%mzn-stat-end
802
803 (the corresponding feasible solution with value 12345 goes here
804 or before its statistics but above the separator)
805 ---------- (<- the solution separator)
806
807 %%%mzn-stat: objective=379
808 %%%mzn-stat: objectiveBound=379
809 %%%mzn-stat: nodes=4725
810 %%%mzn-stat: solveTime=178.5799
811 %%%mzn-stat-end
812
813 (the corr. optimal solution with value 379 goes here)
814 ----------
815 ========== (<- the 'search complete' marker)
816
817 %%%mzn-stat: objective=379 (<- this is the concluding output)
818 %%%mzn-stat: objectiveBound=379
819 %%%mzn-stat: nodes=13456
820 %%%mzn-stat: solveTime=2378.5799
821 %%%mzn-stat-end
822
823
824The :mzndef:`<name>` describes the kind of statistics gathered, and the :mzndef:`<value>` can be any value of a MiniZinc type.
825The following names are considered standard statistics:
826
827======================== ====== ================================================
828Name Type Explanation
829======================== ====== ================================================
830``nodes`` int Number of search nodes
831``openNodes`` int Number of open search nodes
832``objective`` float Current objective value
833``objectiveBound`` float Dual bound on the objective value
834``failures`` int Number of leaf nodes that were failed
835``restarts`` int Number of times the solver restarted the search
836``variables`` int Number of variables
837``intVariables`` int Number of integer variables created
838``boolVariables`` int Number of bool variables created
839``floatVariables`` int Number of float variables created
840``setVariables`` int Number of set variables created
841``propagators`` int Number of propagators created
842``propagations`` int Number of propagator invocations
843``peakDepth`` int Peak depth of search tree
844``nogoods`` int Number of nogoods created
845``backjumps`` int Number of backjumps
846``peakMem`` float Peak memory (in Mbytes)
847``initTime`` float Initialisation time (in seconds)
848``solveTime`` float Solving time (in seconds)
849======================== ====== ================================================
850
851Error and warning output
852~~~~~~~~~~~~~~~~~~~~~~~~
853
854Errors and warnings must be output to the standard error stream. When an error occurs, the implementation should exit with a non-zero exit code, signaling failure.
855
856
857.. _ch-solver-specific-libraries:
858
859Solver-specific Libraries
860-------------------------
861
862Constraints in FlatZinc can call standard predicates as well as solver-specific predicates. Standard predicates are the ones that the MiniZinc compiler assumes to be present in all solvers. Without further customisation, the compiler will try to compile the entire model into a set of these standard predicates.
863
864Solvers can use custom predicates and *redefine* standard predicates by supplying a *solver specific library* of predicate declarations. Examples of such libraries can be found in the binary distribution of MiniZinc, inside the ``share/minizinc/gecode`` and ``share/minizinc/chuffed`` directories.
865
866The solver-specific library needs to be made available to the MiniZinc compiler by specifying its location in the solver's configuration file, see :numref:`sec-cmdline-conffiles`.
867
868Standard predicates
869~~~~~~~~~~~~~~~~~~~
870
871FlatZinc solvers need to support the predicates listed as ``FlatZinc builtins`` in the library reference documentation, see :numref:`ch-lib-flatzinc`.
872
873Any standard predicate that is not supported by a solver needs to be *redefined*. This can be achieved by placing a file called ``redefinitions.mzn`` in the solver's MiniZinc library, which can contain alternative definitions of predicates, or define them as unsupported using the ``abort`` predicate.
874
875Example for a ``redefinitions.mzn``:
876
877.. code-block:: minizinc
878
879 % Redefine float_sinh function in terms of exp
880 predicate float_sinh(var float: a, var float: b) =
881 b == (exp(a)-exp(-a))/2.0;
882
883 % Mark float_tanh as unsupported
884 predicate float_tanh(var float: a, var float: b) =
885 abort("The builtin float_tanh is not supported by this solver.");
886
887The redefinition can use the full MiniZinc language. Note, however, that redefining builtin predicates in terms of MiniZinc expressions can lead to problems if the MiniZinc compiler translates the high-level expression back to the redefined builtin.
888
889The reference documentation (:numref:`ch-lib-flatzinc`) also contains sections on builtins that were added in later versions of MiniZinc. In order to maintain backwards compatibility with solvers that don't support these, they are organised in redefinition files with a version number attached, such as ``redefinitions-2.0.mzn``. In order to declare support for these builtins, the solver-specific library must contain the corresponding redefinitions file, with the predicates either redefined in terms of other predicates, or declared as supported natively by the solver by providing a predicate declaration without a body.
890
891Example for a ``redefinitions-2.0.mzn`` that declares native support for the predicates added in MiniZinc 2.0:
892
893.. code-block:: minizinc
894
895 predicate bool_clause_reif(array[int] of var bool: as,
896 array[int] of var bool: bs,
897 var bool: b);
898 predicate array_int_maximum(var int: m, array[int] of var int: x);
899 predicate array_float_maximum(var float: m, array[int] of var float: x);
900 predicate array_int_minimum(var int: m, array[int] of var int: x);
901 predicate array_float_minimum(var float: m, array[int] of var float: x);
902
903
904Solver-specific predicates
905~~~~~~~~~~~~~~~~~~~~~~~~~~
906
907Many solvers have built-in support for some of the constraints in the MiniZinc standard library. But without declaring which constraints they support, MiniZinc will assume that they don't support any except for the standard FlatZinc builtins mentioned in the section above.
908
909A solver can declare that it supports a non-standard constraint by overriding one of the files of the standard library in its own solver-specific library. For example, assume that a solver supports the ``all_different`` constraint on integer variables. In the standard library, this constraint is defined in the file ``fzn_all_different_int.mzn``, with the following implementation:
910
911.. code-block:: minizinc
912
913 predicate fzn_all_different_int(array[int] of var int: x) =
914 forall(i,j in index_set(x) where i < j) ( x[i] != x[j] );
915
916A solver, let's call it *OptiSolve*, that supports this constraint natively can place a file with the same name, ``fzn_all_different_int.mzn``, in its library, and redefine it as follows:
917
918.. code-block:: minizinc
919
920 predicate optisolve_alldifferent(array[int] of var int: x);
921
922 predicate fzn_all_different_int(array[int] of var int: x) =
923 optisolve_alldifferent(x);
924
925When a MiniZinc model that contains the ``all_different`` constraint is now compiled with the *OptiSolve* library, the generated FlatZinc will contain calls to the newly defined predicate ``optisolve_alldifferent``.
926
927**Note:** The solver-specific library has been reorganised for MiniZinc version 2.3.0. Previously, a solver library would contain e.g. the file ``bin_packing.mzn`` in order to override the :mzn:`bin_packing` constraint. With version 2.3.0, this is still possible (in order to maintain backwards compatibility). However, the predicate :mzn:`bin_packing` from file ``bin_packing.mzn`` now delegates to the predicate :mzn:`fzn_bin_packing` in ``fzn_bin_packing.mzn``. This enables the :mzn:`bin_packing` predicate to check that the arguments are correct using assertions, before delegating to the solver-specific predicate. If your solver still uses the old library layout (i.e., overriding ``bin_packing.mzn`` instead of ``fzn_bin_packing.mzn``), you should consider updating it to the new standard.
928
929.. _fzn-half-reif:
930
931Reified and half-reified predicates
932~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
933
934A reified constraint is a constraint that is not simply enforced, but whose truth value is bound to a Boolean variable. For example, a MiniZinc expression :mzn:`var bool: b = all_different(x);` would constrain :mzn:`b` to be true if and only if the variables :mzn:`x` take pairwise different values.
935
936If a predicate is called in such a reified context, the MiniZinc compiler will try to find a version of the predicate with :mzn:`_reif` added to its identifier and an additional :mzn:`var bool` argument. For the above example, the compiler will try to generate the following FlatZinc code:
937
938.. code-block:: minizinc
939
940 var bool: b;
941 constraint all_different_reif(x, b);
942
943If the :mzn:`_reif` predicate does not exist, the compiler will try to use the definition of the original predicate. However, this may not be ideal: the original definition may make use of free variables in a :mzn:`let` expression (which is not allowed in reified contexts), or it may lead to inefficient solving.
944
945Solver libraries should therefore provide reified versions of constraints whenever possible. The library contains files ``fzn_<constraintname>_reif.mzn`` for this purpose.
946
947When a reified constraint is used in a *positive context* (see :numref:`pred-context`), the MiniZinc compiler can use a special version, called a half-reified predicate and identified by an :mzn:`_imp` suffix, instead of the :mzn:`_reif` predicate. Half-reified predicates essentially represent constraints that are *implied* by a Boolean variable rather than being equivalent to one. This typically leads to simpler translations or more efficient propagation (e.g., a half-reified :mzn:`all_different` only needs to *check* whether it is false, but it never has to implement the negation of the actual constraint).
948
949For example, :mzn:`constraint y=0 \/ all_different(x)` might be translated as follows:
950
951.. code-block:: minizinc
952
953 var bool: X_INTRODUCED_1;
954 var bool: X_INTRODUCED_2;
955 constraint int_eq_imp(y,0,X_INTRODUCED_1);
956 constraint all_different_imp(x, X_INTRODUCED_2);
957 constraint array_bool_or([X_INTRODUCED_1,X_INTRODUCED_2]);
958
959MiniZinc will decide whether to use half-reification case by case based on the availability of the :mzn:`_imp` predicate. As for reified constraints, it may be benefitial to provide specialised half-reified versions if the solver supports them.
960
961.. _fzn-cmdline-options:
962
963Command-Line Interface and Standard Options
964-------------------------------------------
965
966In order to work with the ``minizinc`` command line driver, a FlatZinc solver must be an executable (which can include e.g. shell scripts) that can be invoked as follows:
967
968.. code-block:: bash
969
970 $ <executable-name> [options] model.fzn
971
972where ``<executable-name>`` is the name of the executable. Solvers may support the following standard options:
973
974.. option:: -a
975
976 Instructs the solver to report *all* solutions in the case of satisfaction
977 problems, or print *intermediate* solutions of increasing quality in the case
978 of optimisation problems.
979
980.. option:: -n <i>
981
982 Instructs the solver to stop after reporting ``i`` solutions (only used with
983 satisfaction problems).
984
985.. option:: -i
986
987 Instructs the solver to print *intermediate* solutions of increasing quality
988 (only used with optimisation problems). This option should be supported rather
989 than ``-a`` for solvers which only support printing of intermediate solutions
990 for optimisation problems but no reporting of all solutions for satisfaction
991 problems.
992
993.. option:: -f
994
995 Instructs the solver to conduct a "free search", i.e., ignore any search
996 annotations. The solver is not *required* to ignore the annotations, but it
997 is *allowed* to do so.
998
999.. option:: -s
1000
1001 Print statistics during and/or after the search for solutions. Statistics
1002 should be printed as FlatZinc comments to the standard output stream.
1003 See below for a standard format for statistics.
1004
1005.. option:: -v
1006
1007 Print log messages (verbose solving) to the standard error stream. If solvers
1008 choose to print to standard output instead, all messages must be valid
1009 comments (i.e., start with a ``%`` character).
1010
1011.. option:: -p <i>
1012
1013 Run with ``i`` parallel threads (for multi-threaded solvers).
1014
1015.. option:: -r <i>
1016
1017 Use ``i`` as the random seed (for any random number generators the solver
1018 may be using).
1019
1020.. option:: -t <ms>
1021
1022 Wall time limit ``ms`` milliseconds.
1023
1024.. _sec-cmdline-conffiles:
1025
1026Solver Configuration Files
1027--------------------------
1028
1029In order for a solver to be available to MiniZinc, it has to be described in a *solver configuration file*. This is a simple file, in JSON or ``.dzn`` format, that contains some basic information such as the solver's name, version, where its library of global constraints can be found, and a path to its executable.
1030Examples are given in section Solver Backends in User Manual.
1031
1032A solver configuration file must have file extension ``.msc`` (for MiniZinc Solver Configuration), and can be placed in any of the following locations:
1033
1034- In the ``minizinc/solvers/`` directory of the MiniZinc installation. If you install MiniZinc from the binary distribution, this directory can be found at ``/usr/share/minizinc/solvers`` on Linux systems, inside the MiniZincIDE application on macOS system, and in the ``Program Files\MiniZinc IDE (bundled)`` folder on Windows.
1035- In the directory ``$HOME/.minizinc/solvers`` on Linux and macOS systems, and the Application Data directory on Windows systems.
1036- In any directory listed on the ``MZN_SOLVER_PATH`` environment variable (directories are separated by ``:`` on Linux and macOS, and by ``;`` on Windows systems).
1037- In any directory listed in the ``mzn_solver_path`` option of the global or user-specific configuration file (see :numref:`ch-user-config`)
1038- Alternatively, you can use the MiniZinc IDE to create solver configuration files, see :numref:`sec-ide-add-solvers` for details.
1039
1040Solver configuration files must be valid JSON or ``.dzn`` files. As a JSON file, it must be an object with certain fields. As a ``.dzn`` file, it must consist of assignment items.
1041
1042For example, a simple solver configuration in JSON format could look like this:
1043
1044.. code-block:: json
1045
1046 {
1047 "name" : "My Solver",
1048 "version": "1.0",
1049 "id": "org.myorg.my_solver",
1050 "executable": "fzn-mysolver"
1051 }
1052
1053
1054The same configuration in ``.dzn`` format would look like this:
1055
1056.. code-block:: minizinc
1057
1058 name = "My Solver";
1059 version = "1.0";
1060 id = "org.myorg.my_solver";
1061 executable = "fzn-mysolver";
1062
1063Here is a list of all configuration options recognised by the configuration file parser. Any valid configuration file must at least contain the fields ``name``, ``version``, ``id``, and ``executable``.
1064
1065- ``name`` (string, required): The name of the solver (displayed, together with the version, when you call ``minizinc --solvers``, and in the MiniZinc IDE).
1066- ``version`` (string, required): The version of the solver.
1067- ``id`` (string, required): A unique identifier for the solver, "reverse domain name" notation.
1068- ``executable`` (string, required): The executable for this solver that can run FlatZinc files. This can be just a file name (in which case the solver has to be on the current PATH), or an absolute path to the executable, or a relative path (which is interpreted relative to the location of the configuration file).
1069- ``mznlib`` (string, default ``""``): The solver-specific library of global constraints and redefinitions. This should be the name of a directory (either an absolute path or a relative path, interpreted relative to the location of the configuration file). For solvers whose libraries are installed in the same location as the MiniZinc standard library, this can also take the form ``-G<solverlib>``, e.g., ``-Ggecode`` (this is mostly the case for solvers that ship with the MiniZinc binary distribution).
1070- ``tags`` (list of strings, default empty): Each solver can have one or more tags that describe its features in an abstract way. Tags can be used for selecting a solver using the ``--solver`` option. There is no fixed list of tags, however we recommend using the following tags if they match the solver's behaviour:
1071
1072 - ``"cp"``: for Constraint Programming solvers
1073 - ``"mip"``: for Mixed Integer Programming solvers
1074 - ``"float"``: for solvers that support float variables
1075 - ``"api"``: for solvers that use the internal C++ API
1076
1077- ``stdFlags`` (list of strings, default empty): Which of the standard solver command line flags are supported by this solver. The standard flags are ``-a``, ``-n``, ``-i``, ``-s``, ``-v``, ``-p``, ``-r``, ``-f``, ``-t``.
1078- ``extraFlags`` (list of list of strings, default empty): Extra command line flags supported by the solver. Each entry must be a list of four strings. The first string is the name of the option (e.g. ``"--special-algorithm"``). The second string is a description that can be used to generate help output (e.g. ``"which special algorithm to use"``). The third string specifies the type of the argument (``"int"``, ``"bool"``, ``"float"``, ``"string"`` or ``"opt"``). The fourth string is the default value. The following types have an additional extended syntax:
1079
1080 - ``"int:n:m"`` where ``n`` and ``m`` are integers, gives lower and upper bounds for the supported values
1081 - ``"float:n:m"`` where ``n`` and ``m`` are floating point numbers, gives lower and upper bounds for the supported values
1082 - ``"bool:onstring:offstring"`` specifies strings to add to the command line flag to turn it on (``onstring``) and off (``offstring``). E.g., ``["-interrupt","whether to catch Ctrl-C","bool:false:true","true"]`` specifies a command line option that can be called as ``-interrupt true`` or ``-interrupt false``. The standard behaviour (just ``"bool"``) means that the option is either added to the command line or not.
1083 - ``"opt:first option:second option:...:last option"`` specifies a list of possible values for the option
1084
1085- ``supportsMzn`` (bool, default ``false``): Whether the solver can run MiniZinc directly (i.e., it implements its own compilation or interpretation of the model).
1086- ``supportsFzn`` (bool, default ``true``): Whether the solver can run FlatZinc. This should be the case for most solvers
1087- ``needsSolns2Out`` (bool, default ``true``): Whether the output of the solver needs to be passed through the MiniZinc output processor.
1088- ``needsMznExecutable`` (bool, default ``false``): Whether the solver needs to know the location of the MiniZinc executable. If true, it will be passed to the solver using the ``mzn-executable`` option.
1089- ``needsStdlibDir`` (bool, default ``false``): Whether the solver needs to know the location of the MiniZinc standard library directory. If true, it will be passed to the solver using the ``stdlib-dir`` option.
1090- ``isGUIApplication`` (bool, default ``false``): Whether the solver has its own graphical user interface, which means that MiniZinc will detach from the process and not wait for it to finish or to produce any output.
1091
1092.. _ch-fzn-syntax:
1093
1094Grammar
1095-------
1096
1097This is the full grammar for FlatZinc. It is a proper subset of the MiniZinc grammar (see :numref:`spec-grammar`). However, instead of specifying all the cases in the MiniZinc grammar that do *not* apply to FlatZinc, the BNF syntax below contains only the relevant syntactic constructs. It uses the same notation as in :numref:`spec-syntax-notation`.
1098
1099.. literalinclude:: fzn-grammar.mzn
1100 :language: minizincdef