this repo has no description
1.. _sec-modelling:
2
3Basic Modelling in MiniZinc
4===========================
5
6.. highlight:: minizinc
7 :linenothreshold: 5
8
9In this section we introduce the basic structure of a MiniZinc model using two simple examples.
10
11Our First Example
12-----------------
13
14.. _fig-aust:
15
16.. figure:: figures/aust.*
17
18 Australian states
19
20As our first example, imagine that we wish to colour a map
21of Australia as shown in :numref:`fig-aust`.
22It is made up of seven different states and territories
23each of which must be given a colour so that adjacent regions
24have different colours.
25
26
27.. literalinclude:: examples/aust.mzn
28 :language: minizinc
29 :caption: A MiniZinc model :download:`aust.mzn <examples/aust.mzn>` for colouring the states and territories in Australia
30 :name: ex-aust
31
32We can model this problem very easily in MiniZinc. The model is shown in :numref:`ex-aust`.
33The first line in the model is a comment. A comment starts with a ``%`` which indicates that the rest of the line is a comment.
34MiniZinc also has C-style block comments,
35which start with ``/*`` and end with ``*/``.
36
37The next part of the model declares the variables in the model.
38The line
39
40::
41
42 int: nc = 3;
43
44specifies a :index:`parameter` in the problem which is the
45number of colours to be used.
46Parameters are similar to (constant) variables in most programming languages.
47They must be
48declared and given a :index:`type`. In this case the type is :mzn:`int`.
49They are given a value by an :index:`assignment`.
50MiniZinc allows the assignment to be included as part of the declaration
51(as in the line above) or to be a separate assignment statement.
52Thus the following is equivalent to the single line above
53
54::
55
56 int: nc;
57 nc = 3;
58
59Unlike variables in many programming languages a parameter can only be given a
60*single* value, in that sense they are named constants.
61It is an error for a parameter to occur in more than one assignment.
62
63The basic :index:`parameter types <single: type; parameter>`
64are :index:`integers <integer>` (:mzn:`int`),
65floating point numbers (:mzn:`float`),
66:index:`Booleans <Boolean>` (:mzn:`bool`) and
67:index:`strings <string>` (:mzn:`string`).
68Arrays and sets are also supported.
69
70.. index::
71 see: decision variable; variable
72
73MiniZinc models can also contain another kind of variable called a
74*decision variable*.
75:index:`Decision variables <variable>` are variables in the sense of mathematical or logical
76variables.
77Unlike parameters and variables in a standard programming language, the
78modeller does not need to give them a value.
79Rather the value of a decision variable is unknown and it is only when the
80MiniZinc model is executed that the solving system determines if the
81decision variable can be assigned a value that satisfies the constraints in the
82model and if so what this is.
83
84In our example model we associate a *decision variable* with each region,
85``wa``, ``nt``, ``sa``, ``q``, ``nsw``, ``v`` and ``t``,
86which stands for the (unknown) colour to be used to fill the region.
87
88.. index::
89 single: domain
90
91For each decision variable we need to give the set of possible values the
92variable can take. This is called the variable's
93*domain*.
94This can be given as part of the :index:`variable declaration <variable; declaration>` and the
95:index:`type` of the decision variable is inferred from the type of the values in the domain.
96
97In MiniZinc decision variables
98can be Booleans, integers, floating point numbers,
99or sets.
100Also supported are arrays whose elements are
101decision variables.
102In our MiniZinc model we use integers to model the different colours. Thus each of our
103decision variables is declared to have the domain :mzn:`1..nc`
104which is an integer range expression
105indicating the set :math:`\{ 1, 2, \dots, nc \}`
106using the :mzn:`var` declaration.
107The type of the values is integer so all of the variables in the model are integer decision variables.
108
109.. defblock:: Identifiers
110
111 Identifiers, which are used to name parameters and variables,
112 are sequences of lower and uppercase
113 alphabetic characters, digits and the underscore ``_`` character. They must
114 start with an alphabetic character. Thus ``myName_2`` is a valid
115 identifier. MiniZinc
116 *keywords* are not allowed to be
117 used as identifier names, they are listed in :ref:`spec-identifiers`.
118 Neither are MiniZinc *operators*
119 allowed to be used as identifier names;
120 they are listed in :ref:`spec-Operators`.
121
122MiniZinc carefully
123distinguishes between the two kinds of model variables:
124parameters and decision variables. The kinds of expressions that can be
125constructed using decision variables are more restricted than those that can
126be built from parameters. However, in any place that a decision variable can be
127used, so can a parameter of the same type.
128
129.. defblock:: Integer Variable Declarations
130
131 An :index:`integer parameter variable <variable; declaration; integer>` is declared as either:
132
133 .. code-block:: minizincdef
134
135 int : <var-name>
136 <l> .. <u> : <var-name>
137
138 where :mzndef:`<l>` and :mzndef:`<u>` are fixed integer expressions.
139
140 An integer decision variable is declared
141 as either:
142
143 .. code-block:: minizincdef
144
145 var int : <var-name>
146 var <l>..<u> : <var-name>
147
148 where :mzndef:`<l>` and :mzndef:`<u>` are fixed integer expressions.
149
150
151Formally the distinction between parameters and decision variables is called
152the *instantiation* of the variable.
153The combination of variable instantiation and type is called a
154:index:`type-inst`.
155As you start to use MiniZinc you will undoubtedly see examples of
156*type-inst* errors.
157
158.. index::
159 single: constraint
160
161The next component of the model are the *constraints*.
162These specify the Boolean expressions that the decision variables must satisfy
163to be a valid solution to the model.
164In this case we have a number of not equal constraints between the decision
165variables enforcing that if two states are adjacent then they must have
166different colours.
167
168.. defblock:: Relational Operators
169
170 MiniZinc provides the :index:`relational operators <operator; relational>`:
171
172 .. index::
173 single: =
174 single: ==
175 single: !=
176 single: <
177 single: <=
178 single: >
179 single: >=
180
181 equal (``=`` or ``==``), not equal
182 (``!=``),
183 strictly less than (``<``),
184 strictly greater than (``>``),
185 less than or equal to (``<=``), and
186 greater than or equal to (``>=``).
187
188
189The next line in the model:
190
191::
192
193 solve satisfy;
194
195indicates the kind of problem it is.
196In this case it is a :index:`satisfaction` problem:
197we wish to find a value for the
198decision variables that satisfies the constraints but we do not care which one.
199
200.. index::
201 single: output
202
203The final part of the model is the *output* statement. This tells MiniZinc what to
204print when the model has been run and a :index:`solution` is found.
205
206.. defblock:: Output and Strings
207
208 .. index::
209 single: output
210 single: string
211 single: show
212
213 An output statement is followed by a *list* of strings. These are
214 typically either :index:`string literals <string; literal>`
215 which are written between double quotes and
216 use a C like notation for special characters,
217 or an expression of the form :mzn:`show(e)`
218 where :mzn:`e` is a MiniZinc expression.
219 In the example ``\n``
220 represents the newline character and ``\t`` a
221 tab.
222
223 There are also formatted varieties of :mzn:`show` for numbers:
224 :mzn:`show_int(n,X)`
225 outputs the value of integer
226 ``X`` in at least :math:`|n|` characters, right justified
227 if :math:`n > 0` and left justified otherwise;
228 :mzn:`show_float(n,d,X)`
229 outputs the value of float ``X`` in at least :math:`|n|` characters, right justified
230 if :math:`n > 0` and left justified otherwise, with :math:`d` characters after the
231 decimal point.
232
233 :index:`String literals <string; literal>` must fit on a single line. Longer string literals can be
234 split across multiple lines using the string concatenation operator
235 ``++``.
236 For example, the string literal
237
238 ::
239
240 "Invalid datafile: Amount of flour is non-negative"
241
242 is equivalent to the string literal expression
243
244 ::
245
246 "Invalid datafile: " ++
247 "Amount of flour is non-negative"
248
249 MiniZinc supports
250 :index:`interpolated strings <string; literal; interpolated>`.
251 Expressions can be embedded directly in string literals,
252 where a sub string of the form :mzn:`"\(e)"`
253 is replaced by the result of :mzn:`show(e)`.
254 For example :mzn:`"t=\(t)\n"` produces the same string as
255 :mzn:`"t=" ++ show(t) ++ "\n"`.
256
257 A model can contain multiple output statements. In that case, all outputs
258 are concatenated in the order they appear in the model.
259
260We can evaluate our model by clicking the *Run* button in the MiniZinc IDE, or by typing
261
262.. code-block:: bash
263
264 $ minizinc --solver gecode aust.mzn
265
266where :download:`aust.mzn <examples/aust.mzn>`
267is the name of the file containing our MiniZinc model.
268We must use the file extension ``.mzn`` to indicate a MiniZinc model.
269The command ``minizinc`` with the option ``--solver gecode``
270uses the Gecode finite domain solver to evaluate
271our model. If you use the MiniZinc binary distribution,
272this solver is in fact the default, so you can just run ``minizinc aust.mzn`` instead.
273
274When we run this we obtain the result:
275
276.. code-block:: none
277
278 wa=3 nt=2 sa=1
279 q=3 nsw=2 v=3
280 t=1
281 ----------
282
283
284.. index::
285 single: solution; separator ----------
286
287The line of 10 dashes ``----------`` is automatically added
288by the MiniZinc output to indicate a solution has been found.
289
290An Arithmetic Optimisation Example
291----------------------------------
292
293Our second example is motivated by the need to bake some cakes for a fete at
294our local school.
295We know how to make two sorts of cakes (WARNING: please don't use
296these recipes at home).
297A banana cake which takes 250g of self-raising flour, 2 mashed bananas, 75g
298sugar and 100g of butter, and a chocolate cake which takes 200g of self-raising
299flour, 75g of cocoa, 150g sugar and 150g of butter.
300We can sell a chocolate cake for $4.50 and a banana cake for $4.00. And we
301have 4kg self-raising flour, 6 bananas, 2kg of sugar, 500g of butter and 500g
302of cocoa.
303The question is how many of each sort of cake should we bake for the fete to
304maximise the profit.
305A possible
306MiniZinc model is shown in :numref:`ex-cakes`.
307
308.. literalinclude:: examples/cakes.mzn
309 :language: minizinc
310 :caption: Model for determining how many banana and chocolate cakes to bake for the school fete (:download:`cakes.mzn <examples/cakes.mzn>`)
311 :name: ex-cakes
312
313.. index::
314 single: expression; arithmetic
315
316The first new feature is the use of *arithmetic expressions*.
317
318.. defblock:: Integer Arithmetic Operators
319
320 .. index::
321 single: operator; integer
322 single: +
323 single: -
324 single: div
325 single: *
326 single: mod
327
328 MiniZinc provides the standard integer arithmetic operators.
329 Addition (``+``),
330 subtraction (``-``),
331 multiplication (``*``),
332 integer division (:mzn:`div`)
333 and
334 integer modulus (:mzn:`mod`).
335 It also provides ``+`` and ``-``
336 as unary operators.
337
338 Integer modulus is defined to give a result :math:`a` :mzn:`mod` :math:`b`
339 that has the same sign as the
340 dividend :math:`a`. Integer division is defined so that
341 :math:`a = b ` ``*`` :math:`(a` :mzn:`div` :math:`b) + (a` :mzn:`mod` :math:`b)`.
342
343 MiniZinc provides standard integer functions for
344 absolute value (:mzn:`abs`) and power function (:mzn:`pow`).
345 For example :mzn:`abs(-4)` and :mzn:`pow(2,5)` evaluate to
346 ``4`` and ``32`` respectively.
347
348 The syntax for arithmetic literals is reasonably standard. Integer literals
349 can be decimal, hexadecimal or octal. For instance ``0``, ``5``,
350 ``123``, ``0x1b7``, ``0o777``.
351
352.. index::
353 single: optimization
354 single: objective
355 single: maximize
356 single: minimize
357
358The second new feature shown in the example is optimisation. The line
359
360::
361
362 solve maximize 400 * b + 450 * c;
363
364specifies that we want to find a solution that maximises the expression in
365the solve statement called the
366*objective*.
367The objective can be any
368kind of arithmetic expression. One can replace the keyword
369:mzn:`maximize`
370by :mzn:`minimize` to specify a minimisation problem.
371
372When we run this we obtain the result:
373
374.. code-block:: none
375
376 no. of banana cakes = 2
377 no. of chocolate cakes = 2
378 ----------
379 ==========
380
381.. index::
382 single: solution; end `==========`
383
384The line ``==========``
385is output automatically for optimisation problems when the system has proved
386that a solution is optimal.
387
388
389.. index::
390 single: data file
391
392Datafiles and Assertions
393------------------------
394
395A drawback of this model is that if we wish to solve a similar problem the
396next time we need to bake cakes for the school (which is often) we need to
397modify the constraints in the model to reflect the ingredients that we have
398in the pantry. If we want to reuse the model then we would be better off to
399make the amount of each ingredient a parameter of the model and then set
400their values at the top of the model.
401
402Even better would be to set the value of these parameters in a separate
403*data file*.
404MiniZinc (like most other modelling languages) allows the
405use of data files to set the value of parameters declared in the original
406model. This allows the same model to be easily used with different data by
407running it with different data files.
408
409Data files must have the file extension ``.dzn`` to indicate a MiniZinc data file
410and a model can be run with any number of data files (though a variable/parameter can only be assigned a value in one file).
411
412.. literalinclude:: examples/cakes2.mzn
413 :language: minizinc
414 :caption: Data-independent model for determining how many banana and chocolate cakes to bake for the school fete (:download:`cakes2.mzn <examples/cakes2.mzn>`)
415 :name: ex-cakes2
416
417Our new model is shown in :numref:`ex-cakes2`.
418We can run it using the command
419
420.. code-block: bash
421
422 $ minizinc cakes2.mzn pantry.dzn
423
424where the data file :download:`pantry.dzn <examples/pantry.dzn>` is defined in
425:numref:`fig-pantry1`. This gives the same result as :download:`cakes.mzn <examples/cakes.mzn>`.
426The output from running the command
427
428.. code-block:: bash
429
430 $ minizinc cakes2.mzn pantry2.dzn
431
432with an alternate data set defined in
433:numref:`fig-pantry2` is
434
435.. code-block:: none
436
437 no. of banana cakes = 3
438 no. of chocolate cakes = 8
439 ----------
440 ==========
441
442If we remove the output statement from :download:`cakes.mzn <examples/cakes.mzn>` then
443MiniZinc will use a default output. In this case the resulting
444output will be
445
446.. code-block:: none
447
448 b = 3;
449 c = 8;
450 ----------
451 ==========
452
453.. defblock:: Default Output
454
455 A MiniZinc model with no output will output a line for each
456 decision variable with its value, unless it is assigned an expression
457 on its declaration. Note how the output is in the form of a correct datafile.
458
459.. literalinclude:: examples/pantry.dzn
460 :language: minizinc
461 :caption: Example data file for :download:`cakes2.mzn <examples/cakes2.mzn>` (:download:`pantry.dzn <examples/pantry.dzn>`)
462 :name: fig-pantry1
463
464.. literalinclude:: examples/pantry2.dzn
465 :language: minizinc
466 :caption: Example data file for :download:`cakes2.mzn <examples/cakes2.mzn>` (:download:`pantry2.dzn <examples/pantry2.dzn>`)
467 :name: fig-pantry2
468
469Small data files can be entered
470without directly creating a ``.dzn``
471file, using the :index:`command line flag <data file;command line>`
472``-D`` *string*,
473where *string* is the contents of the data
474file. For example the command
475
476.. code-block:: bash
477
478 $ minizinc cakes2.mzn -D \
479 "flour=4000;banana=6;sugar=2000;butter=500;cocoa=500;"
480
481will give identical results to
482
483.. code-block:: bash
484
485 $ minizinc cakes2.mzn pantry.dzn
486
487Data files can only contain assignment statements for
488decision variables and parameters in the model(s) for which they are intended.
489
490.. index::
491 single: assert
492
493Defensive programming suggests that we should check that the values in the
494data file are reasonable. For our example it is sensible to check that the
495quantity of all ingredients is non-negative and generate a run-time error if
496this is not true. MiniZinc provides a built-in Boolean operator for checking
497parameter values. The form is :mzn:`assert(B,S)`. The Boolean expression
498``B`` is evaluated and if it is false execution aborts and the string
499expression ``S`` is evaluated and printed as an error message. To check and
500generate an appropriate error message if the amount of flour is negative we
501can simply add the line
502
503::
504
505 constraint assert(flour >= 0,"Amount of flour is non-negative");
506
507to our model. Notice that the :mzn:`assert` expression is a Boolean
508expression and so is regarded as a type of constraint. We can add similar
509lines to check that the quantity of the other ingredients is non-negative.
510
511Real Number Solving
512-------------------
513
514MiniZinc also supports "real number" constraint solving using
515floating point variables and constraints. Consider a problem of taking out a short loan
516for one year to be repaid in 4 quarterly instalments.
517A model for this is shown in :numref:`ex-loan`. It uses a simple interest
518calculation to calculate the balance after each quarter.
519
520.. literalinclude:: examples/loan.mzn
521 :language: minizinc
522 :caption: Model for determining relationships between a 1 year loan repaying every quarter (:download:`loan.mzn <examples/loan.mzn>`)
523 :name: ex-loan
524
525Note that we declare a float variable ``f``
526similar to an integer variable using the keyword :mzn:`float` instead of
527:mzn:`int`.
528
529We can use the same model to answer a number of different questions.
530The first question is: if I borrow $1000 at 4% and repay $260 per
531quarter, how much do I end up owing? This question is encoded by
532the data file :download:`loan1.dzn <examples/loan1.dzn>`.
533
534Since we wish to use real number variables and constraint we need to use a solver
535that supports this type of problem. While Gecode (the default solver in the MiniZinc bundled binary distribution) does support floating point variables, a mixed integer linear programming (MIP) solver may be better suited to this particular type of problem.
536The MiniZinc distribution contains such a solver. We can invoke it by selecting ``COIN-BC`` from the solver menu in the IDE (the triangle below the *Run* button), or on the command line using the command ``minizinc --solver cbc``:
537
538.. code-block:: bash
539
540 $ minizinc --solver cbc loan.mzn loan1.dzn
541
542The output is
543
544.. code-block:: none
545
546 Borrowing 1000.00 at 4.0% interest, and repaying 260.00
547 per quarter for 1 year leaves 65.78 owing
548 ----------
549
550The second question is if I want to borrow $1000 at 4% and owe nothing at
551the end, how much do I need to repay?
552This question is encoded by
553the data file :download:`loan2.dzn <examples/loan2.dzn>`.
554The output from running the command
555
556.. code-block:: bash
557
558 $ minizinc --solver cbc loan.mzn loan2.dzn
559
560is
561
562.. code-block:: none
563
564 Borrowing 1000.00 at 4.0% interest, and repaying 275.49
565 per quarter for 1 year leaves 0.00 owing
566 ----------
567
568The third question is if I can repay $250 a quarter, how much can I borrow
569at 4% to end up owing nothing?
570This question is encoded by the data file :download:`loan3.dzn <examples/loan3.dzn>`.
571The output from running the command
572
573.. code-block:: bash
574
575 $ minizinc --solver cbc loan.mzn loan3.dzn
576
577is
578
579.. code-block:: none
580
581 Borrowing 907.47 at 4.0% interest, and repaying 250.00
582 per quarter for 1 year leaves 0.00 owing
583 ----------
584
585.. literalinclude:: examples/loan1.dzn
586 :language: minizinc
587 :caption: Example data file for :download:`loan.mzn <examples/loan.mzn>` (:download:`loan1.dzn <examples/loan1.dzn>`)
588
589.. literalinclude:: examples/loan2.dzn
590 :language: minizinc
591 :caption: Example data file for :download:`loan.mzn <examples/loan.mzn>` (:download:`loan2.dzn <examples/loan2.dzn>`)
592
593.. literalinclude:: examples/loan3.dzn
594 :language: minizinc
595 :caption: Example data file for :download:`loan.mzn <examples/loan.mzn>` (:download:`loan3.dzn <examples/loan3.dzn>`)
596
597
598.. defblock:: Float Arithmetic Operators
599
600 .. index:
601 single: operator; float
602 single: +
603 single: -
604 single: *
605 single: /
606 single: abs
607 single: sqrt
608 single: ln
609 single: log2
610 single: log10
611 single: exp
612 single: sin
613 single: cos
614 single: tan
615 single: asin
616 single: acos
617 single: atan
618 single: sinh
619 single: cosh
620 single: tanh
621 single: asinh
622 single: acosh
623 single: atanh
624 single: pow
625
626 MiniZinc provides the standard floating point arithmetic operators:
627 addition (``+``),
628 subtraction (``-``),
629 multiplication (``*``)
630 and floating point division (``/``).
631 It also provides ``+`` and ``-`` as unary operators.
632
633 MiniZinc can automatically coerce integers to
634 floating point numbers. But to make the coercion explicit, the built-in function
635 :mzn:`int2float`
636 can be used. Note that one consequence of the automatic coercion is that
637 an expression :mzn:`a / b` is always considered a floating point division. If
638 you need an integer division, make sure to use the :mzn:`div` operator!
639
640 MiniZinc provides in addition the following floating point functions:
641 absolute value (``abs``),
642 square root (``sqrt``),
643 natural logarithm (``ln``),
644 logarithm base 2 (``log2``),
645 logarithm base 10 (``log10``),
646 exponentiation of $e$ (``exp``),
647 sine (``sin``),
648 cosine (``cos``),
649 tangent (``tan``),
650 arcsine (``asin``),
651 arc\-cosine (``acos``),
652 arctangent (``atan``),
653 hyperbolic sine (``sinh``),
654 hyperbolic cosine (``cosh``),
655 hyperbolic tangent (``tanh``),
656 hyperbolic arcsine (``asinh``),
657 hyperbolic arccosine (``acosh``),
658 hyperbolic arctangent (``atanh``),
659 and power (``pow``) which is the only binary function, the rest are
660 unary.
661
662 The syntax for arithmetic literals is reasonably standard. Example float
663 literals are ``1.05``, ``1.3e-5`` and ``1.3E+5``.
664
665.. \pjs{Should do multiple solutions????}
666
667Basic structure of a model
668--------------------------
669
670We are now in a position to summarise the basic structure of a MiniZinc model.
671It consists of multiple *items* each of which has a
672semicolon ``;`` at its end.
673Items can occur in any order.
674For example, identifiers need not be declared before they are
675used.
676
677There are 8 kinds of :index:`items <item>`.
678
679- :index:`Include items <item; include>` allow the contents of another file to be inserted into the model.
680 They have the form:
681
682 .. code-block:: minizincdef
683
684 include <filename>;
685
686 where :mzndef:`<filename>` is a string literal.
687 They allow large models to be split into smaller sub-models and also the
688 inclusion of constraints defined in library files.
689 We shall see an example in :numref:`ex-smm`.
690
691- :index:`Variable declarations <item; variable declaration>` declare new variables.
692 Such variables are global variables and can be referred to from anywhere in the
693 model.
694 Variables come in two kinds.
695 Parameters which are assigned a fixed value in the model or in a data file and
696 decision variables whose value is found only when the model is solved.
697 We say that parameters are :index:`fixed` and decision variables are
698 :index:`unfixed`.
699 The variable can be optionally assigned a value as part of the declaration.
700 The form is:
701
702 .. index:
703 single: expression; type-inst
704 single: par
705 single: var
706
707 .. code-block:: minizincdef
708
709 <type inst expr>: <variable> [ = ] <expression>;
710
711 The :mzndef:`<type-inst expr>`
712 gives the instantiation and type of the
713 variable. These are one of the more complex aspects of MiniZinc.
714 Instantiations are declared using :mzn:`par`
715 for parameters and
716 :mzn:`var` for decision variables. If there is no explicit instantiation
717 declaration then the variable is a parameter.
718 The type can be a base type,
719 an :index:`integer or float range <range>`
720 or an array or a set.
721 The base types are :mzn:`float`,
722 :mzn:`int`,
723 :mzn:`string`,
724 :mzn:`bool`,
725 :mzn:`ann`
726 of which only
727 :mzn:`float`, :mzn:`int` and :mzn:`bool` can be used for decision
728 variables.
729 The base type :mzn:`ann` is an :index:`annotation` --
730 we shall discuss
731 annotations in :ref:`sec-search`.
732 :index:`Integer range expressions <range; integer>` can be used
733 instead of the type :mzn:`int`.
734 Similarly :index:`float range expressions <range; float>`
735 can be used instead of type :mzn:`float`.
736 These are typically used to give the
737 domain of a decision variable but can also be used to restrict the
738 range of a parameter. Another use of variable declarations is to
739 define :index:`enumerated types`, which we discuss in :ref:`sec-enum`.
740
741- :index:`Assignment items <item; assignment>` assign a value to a variable. They have the form:
742
743 .. code-block:: minizincdef
744
745 <variable> = <expression>;
746
747 Values can be assigned to decision variables in which case the assignment is
748 equivalent to writing :mzndef:`constraint <variable> = <expression>`.
749
750- :index:`Constraint items <item; constraint>` form the heart of the model. They have the form:
751
752 .. code-block:: minizincdef
753
754 constraint <Boolean expression>;
755
756 We have already seen examples of simple constraints using arithmetic
757 comparison and the built-in :mzn:`assert` operator. In the next section we
758 shall see examples of more complex constraints.
759
760- :index:`Solve items <item; solve>` specify exactly what kind of solution is being looked for.
761 As we have seen they have one of three forms:
762
763 .. code-block:: minizincdef
764
765 solve satisfy;
766 solve maximize <arithmetic expression>;
767 solve minimize <arithmetic expression>;
768
769 A model is required to have at most one solve item. If it's omitted, it is
770 treated as :mzn:`solve satisfy`.
771
772- :index:`Output items <item; output>` are for nicely presenting the results of the model execution.
773 They have the form:
774
775 .. code-block:: minizincdef
776
777 output [ <string expression>, ..., <string expression> ];
778
779 If there is no output item, MiniZinc will by default print out the values of
780 all the decision variables which are not optionally assigned a value in the
781 format of assignment items.
782
783- :index:`Enumerated type declarations <item; enum>`.
784 We discuss these in :ref:`sec-arrayset` and :ref:`sec-enum`.
785
786- :index:`Predicate, function and test items <item; predicate>` are for defining new constraints,
787 functions and Boolean tests.
788 We discuss these in :ref:`sec-predicates`.
789
790
791- The :index:`annotation item <item; annotation>` is used to define a new annotation. We
792 discuss these in :ref:`sec-search`.