this repo has no description
at develop 26 kB view raw
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`.