this repo has no description
1.. _sec-modelling:
2
3Modelamiento básico en MiniZinc
4===============================
5
6.. highlight:: minizinc
7 :linenothreshold: 5
8
9En esta sección se presenta la estructura básica de un modelo MiniZinc utilizando dos ejemplos simples.
10
11Nuestro primer ejemplo
12----------------------
13
14.. _fig-aust:
15
16.. figure:: figures/aust.*
17
18 Estados de Australia
19
20Como nuestro primer ejemplo, imagine que se desea colorear el mapa de Australia, tal como se ve en la figura :numref:`fig-aust`.
21
22Esta figura se compone de siete estados diferentes, cada uno de los estados debe de tener un color y cada región adyacentes tiene que poseer diferentes colores.
23
24.. literalinclude:: examples/aust_es.mzn
25 :language: minizinc
26 :caption: Un modelo de MiniZinc :download:`aust_es.mzn <examples/aust_es.mzn>` para colorear los estados y territorios en Australia
27 :name: ex-aust
28
29Este problema se puede modelar muy fácil en MiniZinc. El modelo se muestra en :numref:`ex-aust`.
30
31La primera línea del modelo corresponde a un comentario. Un comentario comienza con un ``%``, que indica que el resto de la línea es un comentario.
32
33MiniZinc también tiene comentarios de bloque similares al estilo del lenguaje de programación C. Este tipo de comentario comienzan con ``/*`` y finalizan con un ``*/``.
34
35La siguiente parte del modelo declara las variables en el modelo.
36
37La línea
38
39::
40
41 int: nc = 3;
42
43especifica un :index:`parámetro` en el problema, el cual es el número de colores a ser utilizados.
44
45Los parámetros son similares a las variables (constantes) de la mayoría de los lenguajes de programación.
46
47Estos deben de ser declarados y se debe de especificar un :index:`tipo` de dato.
48En este caso, el tipo de dato es :mzn:`int`.
49
50Además se le debe de dar un valor al parámetro mediante una :index:`asignación`.
51
52MiniZinc permite incluir la asignación como parte de la declaración (como en la línea anterior) o ser una sentencia de asignación separada.
53Así, la siguiente asignación de dos líneas, es equivalente a la asignación de una línea.
54
55::
56
57 int: nc;
58 nc = 3;
59
60A diferencia de las variables, en muchos lenguajes de programación a un parámetro sólo se le puede asignar un solo valor. En ese sentido, son denominadas constantes. Es un error que un parámetro posea más de una asignación.
61
62
63Lo tipos de parámetros básicos son: :index:`enteros <integer>` (:mzn:`int`),
64números de punto flotante (:mzn:`float`),
65:index:`boleanos <Boolean>` (:mzn:`bool`) y
66:index:`cadenas <string>` (:mzn:`string`).
67Arreglos y conjuntos también son soportados.
68
69.. index::
70 see: decision variable; variable
71
72
73Los modelos MiniZinc también pueden contener otro tipo de variable llamadas *variables de decisión*.
74Las :index:`variables de decisión <variable>` son variables en el sentido de las matemáticas o variables lógicas.
75A diferencia de parámetros y variables en un lenguaje de programación estándar, el modelador no necesita darles un valor.
76
77Más bien, el valor de una variable de decisión es desconocido. En consecuencia, es solamente cuando se ejecuta el modelo en MiniZinc, que el sistema de resolución determina si la variable de decisión se puede asignar un valor que satisface las restricciones en el modelo.
78
79En nuestro modelo de ejemplo, nosotros asociamos una *variable de decisión* a cada estado:
80``wa``, ``nt``, ``sa``, ``q``, ``nsw``, ``v`` y ``t`` que representa el color (desconocido) que se utilizará para llenar la región.
81
82.. index::
83 single: domain
84
85Para cada variable de decisión se necesita dar el conjunto de los posibles valores que la variable puede tomar.
86Esto se llama *dominio* de la variable. Esto se puede dar como parte de la :index:`declaración de la variable <variable; declaration>` y el :index:`tipo` de la variable de decisión se infiere a partir del tipo de los valores en el dominio.
87
88En MiniZinc, las variables de decisión pueden ser booleanas, enteras, números de punto flotante o conjuntos.
89También se admiten las matrices cuyos elementos son variables de decisión. En nuestro modelo MiniZinc usamos números enteros para modelar los diferentes colores.
90Por lo tanto, cada una de las variables de decisión declarada posee el dominio :mzn:`1..nc`.
91Este dominio declarado es una expresión de un intervalo de tipo entero indicado por el conjunto :math:`\{ 1, 2, \dots, nc \}` usado en la declaración :mzn:`var`. El tipo de los valores es entero, por lo que todas las variables del modelo son variables de decisión enteras.
92
93
94.. defblock:: Identificadores
95
96 Los identificadores, son utilizados para nombrar parámetros y variables,
97 son secuencias de caracteres alfabéticos de minúsculas y mayúsculas, dígitos y el carácter ``_`` de subrayado .
98 Además, deben de comenzar con un carácter alfabético. Así, ``myName_2`` es un identificador válido.
99
100 Las *palabras clave* en MiniZinc no se pueden utilizar como nombres de identificador. Estas, se encuentran listadas en: ref:`spec-identifiers`.
101
102 Tampoco se permite que los *operadores* de MiniZinc se utilicen como identificadores; el listado aparece en :ref:`spec-Operators`.
103
104
105MiniZinc distingue cuidadosamente entre los dos tipos de variables del modelo: los parámetros y las variables de decisión. Los tipos de expresiones que se pueden construir usando variables de decisión son más restringidos que los que se pueden construir a partir de parámetros. Sin embargo, en cualquier lugar en que se pueda utilizar una variable de decisión, también se puede tener un parámetro del mismo tipo.
106
107
108.. defblock:: Declaraciones de variables enteras
109
110 Una :index:`variable de parámetro entero <variable; declaration; integer>` se declara como:
111
112 .. code-block:: minizincdef
113
114 int : <var-name>
115 <l> .. <u> : <var-name>
116
117 en donde :mzndef:`<l>` y :mzndef:`<u>` son expresiones enteras fijas.
118
119 Una variable de decisión entera se declara como:
120
121 .. code-block:: minizincdef
122
123 var int : <var-name>
124 var <l>..<u> : <var-name>
125
126 en donde :mzndef:`<l>` y :mzndef:`<u>` son expresiones enteras fijas.
127
128
129Formalmente la distinción entre parámetros y variables de decisión se denomina *instanciación* de la variable. La combinación de la instanciación variable y el tipo se llama tipo-instanciación (:index:`type-inst`).
130A medida de que usted empiece a usar MiniZinc, sin duda verá ejemplos de errores de tipo-instanciación (:index:`type-inst`).
131
132.. index::
133 single: constraint
134
135El siguiente componente del modelo son las *restricciones*. Estas especifican las expresiones booleanas que las variables de decisión deben satisfacer para ser una solución válida para el modelo. En este ejemplo, existe un número de restricciones no iguales entre las variables de decisión, las cuales hacen cumplir que si dos estados son adyacentes, entonces deben tener colores diferentes.
136
137.. defblock:: Operadores relacionales
138
139 MiniZinc proporciona los :index:`operadores relacionales <operator; relational>`:
140
141 .. index::
142 single: =
143 single: ==
144 single: !=
145 single: <
146 single: <=
147 single: >
148 single: >=
149
150 igual (``=`` or ``==``), no igual
151 (``!=``),
152 estrictamente menor que (``<``),
153 estrictamente mayor que (``>``),
154 menor o igual a (``<=``), y
155 mayor o igual que (``>=``).
156
157
158La siguiente línea del modelo:
159
160::
161
162 solve satisfy;
163
164
165indica que el tipo de problema que es. En este caso, es un problema de :index:`satisfacción`: es decir, se debe de encontrar un valor para las variables de decisión que satisface las restricciones pero no nos importa cuál.
166
167.. index::
168 single: output
169
170La parte final del modelo es la declaración de *salida*. Esto le indica a MiniZinc lo que debe de imprimir cuando se ejecute el modelo y encuentre una :index:`solución`.
171
172.. defblock:: Salida y cadenas
173
174 .. index::
175 single: output
176 single: string
177 single: show
178
179 Una instrucción de salida es seguida por una *lista* de cadenas. Estos son típicamente :index:`string literales <string; literal>`
180 que se escriben entre comillas dobles y utilizan una notación C para caracteres especiales,
181 o una expresión de la forma :mzn:`show(e)`
182 en donde :mzn:`e` es una espresión de MiniZinc.
183 En el ejemplo ``\n`` representa el carácter de nueva línea y ``\t`` un tabulador.
184
185 También hay variedades de formato :mzn:`show` para números:
186 :mzn:`show_int(n,X)`
187 salidas de valores enteros
188 ``X`` en al menos :math:`|n|` carácteres, justificados a la derecha
189 si :math:`n > 0` y de otro modo, justificado a la izquierda;
190 :mzn:`show_float(n,d,X)`
191 salidas de los valores de punto flotante (mzn:`float`) ``X`` en al menos :math:`|n|` carácteres, justificados a la derecha
192 si :math:`n > 0` y de otro modo, justificado a la izquierda, con :math`d` carácteres después del punto decimal.
193
194 Los :index:`Literales de cadenas <string; literal>` deben encajar en una sola línea. Los literales de cadena más largos se pueden dividir en varias líneas utilizando el operador de concatenación de cadenas ``++``.
195 Por ejemplo, el literal
196
197 ::
198
199 "Archivo de datos no válido: La cantidad de harina no es negativa"
200
201 es equivalente a la expresión literal de cadena
202
203 ::
204
205 "Archivo de datos no válido: " ++
206 "La cantidad de harina no es negativa"
207
208 MiniZinc soporta
209 :index:`cadenas interpoladas <string; literal; interpolated>`.
210 Las expresiones pueden ser incorporados directamente en las cadenas literales,
211 donde una subcadena del forma :mzn:`"\(e)"`
212 es reemplazada por el resultado :mzn:`show(e)`.
213 Por ejemplo, :mzn:`"t=\(t)\n"` produce la misma cadena como :mzn:`"t=" ++ show(t) ++ "\n"`.
214
215 Un modelo puede contener varias declaraciones de salida. En ese caso, todas las salidas se concatenan en el orden en que aparecen en el modelo.
216
217Podemos evaluar nuestro modelo escribiendo
218
219.. code-block:: bash
220
221 $ mzn-gecode aust_es.mzn
222
223en donde :download:`aust_es.mzn <examples/aust_es.mzn>` es el nombre del archivo que contiene nuestro modelo MiniZinc.
224Se debe de utilizar la extensión de archivo ``.mzn`` para indicar un modelo MiniZinc.
225El comando ``mzn-gecode`` utiliza el *solver* de dominios finitos Gecode para evaluar nuestro modelo.
226
227Cuando ejecutamos esto obtenemos el resultado:
228
229.. code-block:: none
230
231 wa=2 nt=3 sa=1
232 q=2 nsw=3 v=2
233 t=1
234 ----------
235
236
237.. index::
238 single: solution; separator ----------
239
240La línea de 10 guiones ``----------`` es automáticamente agregada por la salida de MiniZinc, la cual indica que se ha encontrado una solución.
241
242
243Un ejemplo de optimización aritmética
244-------------------------------------
245
246El segundo ejemplo está motivado por la necesidad de hornear pasteles para una fiesta en nuestra escuela local. Sabemos cómo hacer dos tipos de tortas. \footnote{Advertencia: por favor no utilice estas recetas en casa}
247Un pastel de plátano que toma 250g de harina, 2 plátanos para puré de plátano, 75g de azúcar y 100g de mantequilla. Para un pastel de chocolate se necesita 200g de harina, 75g de cacao, 150g de azúcar y 150g de mantequilla.
248
249Podemos vender un pastel de chocolate por $4.50 y un pastel de plátano por $4.00. Además, tenemos 4kg de harina, 6 plátanos, 2kg de azúcar, 500g de mantequilla y 500g de cacao.
250
251La pregunta es, ¿cuántos de cada tipo de pastel debemos hornear para la fiesta para maximizar el beneficio?.
252
253A continuación se muestra el posible modelo de MiniZinc en :numref:`ex-cakes`.
254
255.. literalinclude:: examples/cakes_es.mzn
256 :language: minizinc
257 :caption: Modelo para determinar cuántos pasteles de banana y chocolate para hornear para la fiesta de la escuela (:download:`cakes_es.mzn <examples/cakes_es.mzn>`)
258 :name: ex-cakes
259
260.. index::
261 single: expression; arithmetic
262
263La primera nueva característica es el uso de *expresiones aritméticas*.
264
265.. defblock:: Operadores Aritméticos Enteros
266
267 .. index::
268 single: operator; integer
269 single: +
270 single: -
271 single: div
272 single: *
273 single: mod
274
275 MiniZinc proporciona los estándar operadores aritméticos enteros.
276
277 Adición (``+``),
278 subtracción (``-``),
279 multiplicación (``*``),
280 división entera (:mzn:`div`)
281 y
282 módulo entero (:mzn:`mod`).
283 También proporciona ``+`` y ``-``
284 como operadores unarios.
285
286 El módulo entero se define para dar un resultado :math:`a` :mzn:`mod` :math:`b`
287 que tiene el mismo signo que el dividendo :math:`a`. La división entera se define de modo que
288 :math:`a = b ` ``*`` :math:`(a` :mzn:`div` :math:`b) + (a` :mzn:`mod` :math:`b)`.
289
290 MiniZinc proporciona funciones enteras estándar para el valor absoluto (:mzn:`abs`) y función de potencia (:mzn:`pow`).
291 Por ejemplo, :mzn:`abs(-4)` y :mzn:`pow(2,5)` es evaluado como ``4`` and ``32`` respectivamente.
292
293 La sintaxis para literales aritméticos es razonablemente estándar. Los literales enteros pueden ser decimales, hexadecimales u octales. Por ejemplo, ``0``, ``5``, ``123``, ``0x1b7``, ``0o777``.
294
295.. index::
296 single: optimization
297 single: objective
298 single: maximize
299 single: minimize
300
301La segunda característica mostrada en el ejemplo es la optimización. La línea
302
303::
304
305 solve maximize 400 * b + 450 * c;
306
307especifica que queremos encontrar una solución que maximice la expresión declarada, esto se denomina *objetivo*.
308
309El objetivo puede ser cualquier tipo de expresión aritmética. Se puede reemplazar la palabra clave
310:mzn:`maximize`
311por :mzn:`minimize` para especificar un problema de minimización.
312
313Cuando ejecutamos esto obtenemos el resultado:
314
315.. code-block:: none
316
317 Número de tortas de plátano = 2
318 Número de tortas de chocolate = 2
319 ----------
320 ==========
321
322.. index::
323 single: solution; end `==========`
324
325La línea ``==========``
326se muestra automáticamente para problemas de optimización cuando el sistema ha demostrado que una solución es óptima.
327
328
329.. index::
330 single: data file
331
332
333Archivos de datos y afirmaciones
334--------------------------------
335
336Un inconveniente de este modelo es que si queremos resolver un problema similar, la próxima vez que necesitamos hornear pasteles para la escuela (que es a menudo) tenemos que modificar las restricciones en el modelo para reflejar los ingredientes que tenemos en la despensa. Si queremos reutilizar el modelo entonces es más conveniente dejar que la cantidad de cada ingrediente sea un parámetro del modelo y luego fijar sus valores en la parte superior del modelo.
337
338Incluso mejor sería establecer el valor de estos parámetros en un archivo de datos separado (*data file*). MiniZinc (como la mayoría de los otros lenguajes de modelado) permite el uso de archivos de datos para establecer el valor de los parámetros declarado en el modelo original. Esto permite que el mismo modelo se utilice fácilmente con diferentes datos ejecutándolo con diferentes archivos de datos.
339
340
341Los archivos de datos deben tener la extensión de archivo ``.dzn`` para indicar un archivo de datos MiniZinc y un modelo se puede ejecutar con cualquier número de archivos de datos (aunque una variable/parámetro sólo se puede asignar un valor en un archivo).
342
343.. literalinclude:: examples/cakes2_es.mzn
344 :language: minizinc
345 :caption: Modelo independiente de los datos para determinar cuántos pasteles de banana y chocolate para hornear para la fiesta de la escuela (:download:`cakes2_es.mzn <examples/cakes2_es.mzn>`)
346 :name: ex-cakes2
347
348Nuestro nuevo modelo se muestra en :numref:`ex-cakes2`.
349Podemos ejecutarlo usando el comando
350
351.. code-block: bash
352
353 $ mzn-gecode cakes2_es.mzn pantry.dzn
354
355donde el archivo de datos :download:`pantry_es.dzn <examples/pantry_es.dzn>` es definido en
356:numref:`fig-pantry1`. Esto da el mismo resultado que :download:`cakes_es.mzn <examples/cakes_es.mzn>`.
357El resultado de la ejecución del comando
358
359.. code-block:: bash
360
361 $ mzn-gecode cakes2_es.mzn pantry2_es.dzn
362
363con un conjunto de datos alternativo definido en
364:numref:`fig-pantry2` is
365
366.. code-block:: none
367
368 Número de tortas de plátano = 3
369 Número de tortas de chocolate = 8
370 ----------
371 ==========
372
373Si eliminamos la instrucción de salida de :download:`cakes_es.mzn <examples/cakes_es.mzn>` entonces MiniZinc utilizará una salida predeterminada. En este caso, la salida resultante será
374
375.. code-block:: none
376
377 b = 3;
378 c = 8;
379 ----------
380 ==========
381
382.. defblock:: Salida por defecto
383
384 A MiniZinc model with no output will output a line for each decision variable with its value, unless it is assigned an expression on its declaration. Note how the output is in the form of a correct datafile.
385
386.. literalinclude:: examples/pantry_es.dzn
387 :language: minizinc
388 :caption: Ejemplo de archivo de datos para :download:`cakes2_es.mzn <examples/cakes2_es.mzn>` (:download:`pantry_es.dzn <examples/pantry_es.dzn>`)
389 :name: fig-pantry1
390
391.. literalinclude:: examples/pantry2_es.dzn
392 :language: minizinc
393 :caption: Ejemplo de archivo de datos para :download:`cakes2_es.mzn <examples/cakes2_es.mzn>` (:download:`pantry2_es.dzn <examples/pantry2_es.dzn>`)
394 :name: fig-pantry2
395
396Se pueden introducir pequeños archivos de datos sin crear un archivo de datos ``.dzn``, usando una :index:`bandera en la línea de comandos <data file;command line>`
397``-D`` *cadena*,
398en donde *cadena* es el contenido del archivo de datos. Por ejemplo, el comando
399
400.. code-block:: bash
401
402 $ mzn-gecode cakes2_es.mzn -D \
403 "flour=4000;banana=6;sugar=2000;butter=500;cocoa=500;"
404
405dará idénticos resultados que
406
407.. code-block:: bash
408
409 $ mzn-g12fd cakes2_es.mzn pantry_es.dzn
410
411Los archivos de datos sólo pueden contener instrucciones de asignación para variables de decisión y parámetros en el modelo o modelos a los que están destinados.
412
413.. index::
414 single: assert
415
416La programación defensiva sugiere que debemos comprobar que los valores en el archivo de datos son razonables. Para nuestro ejemplo es razonable comprobar que la cantidad de todos los ingredientes no es negativa y generar un error en tiempo de ejecución si esto no es cierto.
417
418MiniZinc proporciona un operador (*built-in*) booleano incorporado para comprobar los valores de los parámetros.
419La forma es :mzn:`assert(B,S)`. La expresión booleana ``B`` es evaluada, y si la ejecución es falsa se aborta y la expresión de cadena ``S`` se evalúa e imprime como un mensaje de error. Para comprobar y generar un mensaje de error apropiado si la cantidad de harina es negativa podemos simplemente agregar la línea
420
421::
422
423 constraint assert(flour >= 0,"La cantidad de harina no debe ser negativa");
424
425a nuestro modelo. Observe que la espresión :mzn:`assert` es una expresión booleana y por lo tanto es considerado como un tipo de restricción. Podemos agregar líneas similares para comprobar que la cantidad de los otros ingredientes no es negativa.
426
427
428
429Resolviendo números reales
430--------------------------
431
432Minizinc también soporta la resolución de restricciones con números reales usado en variables de punto flotante y restricciones.
433
434Considere un problema de tomar un préstamo a corto por un año, el cual será reembolsado en 4 cuotas trimestrales.
435
436Un modelo para esto se muestra en :numref:`ex-loan`. Utiliza un cálculo de interés simple para calcular el saldo después de cada trimestre.
437
438.. literalinclude:: examples/loan_es.mzn
439 :language: minizinc
440 :caption: Modelo para determinar las relaciones entre un préstamo de 1 año y lo reembolsado cada trimestre (:download:`loan_es.mzn <examples/loan_es.mzn>`)
441 :name: ex-loan
442
443Tenga en cuenta que declaramos una variable flotante ``f`` similar a una variable entera utilizando la palabra clave :mzn:`float` en lugar de :mzn:`int`.
444
445Podemos utilizar el mismo modelo para responder a una serie de preguntas diferentes.
446La primera pregunta es: Si tomo prestado $1000 al 4% y debo pagar $260 por trimestre, cuánto puedo terminar debiendo?.
447Esta pregunta está codificada por el archivo de datos :download:`loan1_es.dzn <examples/loan1_es.dzn>`.
448
449Puesto que deseamos utilizar variables de números reales y restricción, necesitamos usar un *solver* que soporte este tipo de problema.
450Un solver adecuado sería uno que soporta la programación lineal entera mixta.
451La distribución MiniZinc contiene un *solver*.
452La salida al ejecutar el comando ``mzn-cbc``:
453
454.. code-block:: bash
455
456 $ mzn-cbc loan_es.mzn loan1_es.dzn
457
458La salida es
459
460.. code-block:: none
461
462 Préstamo 1000.00 al 4.0% interés y reembolso 260.00
463 por trimestre para 1 año deja 65.78 debido
464 ----------
465
466La segunda pregunta es: Si tomo prestado $1000 al 4% y no debo nada al final, ¿cuánto tengo que pagar?.
467Esta pregunta está codificada por el archivo de datos :download:`loan2_es.dzn <examples/loan2_es.dzn>`.
468La salida al ejecutar el comando
469
470.. code-block:: bash
471
472 $ mzn-cbc loan_es.mzn loan2_es.dzn
473
474La salida es
475
476.. code-block:: none
477
478 Préstamo 1000.00 al 4.0% interés y reembolso 275.49
479 por trimestre para 1 año deja 0.00 debido
480 ----------
481
482La tercera pregunta, es si puedo pagar $250 por trimestre, ¿cuánto puedo pedir prestado al 4% para terminar por no pagar nada?.
483Esta pregunta está codificada por el archivo de datos :download:`loan3_es.dzn <examples/loan3_es.dzn>`.
484La salida al ejecutar el comando
485
486.. code-block:: bash
487
488 $ mzn-g12mip loan_es.mzn loan3_es.dzn
489
490La salida es:
491
492.. code-block:: none
493
494 Préstamo 907.47 at 4.0% interés y reembolso 250.00
495 por trimestre para 1 año deja 0.00 debido
496 ----------
497
498.. literalinclude:: examples/loan1_es.dzn
499 :language: minizinc
500 :caption: Ejemplo de archivo de datos para :download:`loan_es.mzn <examples/loan_es.mzn>` (:download:`loan1_es.dzn <examples/loan1_es.dzn>`)
501
502.. literalinclude:: examples/loan2_es.dzn
503 :language: minizinc
504 :caption: Ejemplo de archivo de datos para :download:`loan_es.mzn <examples/loan_es.mzn>` (:download:`loan2.dzn <examples/loan2_es.dzn>`)
505
506.. literalinclude:: examples/loan3_es.dzn
507 :language: minizinc
508 :caption: Ejemplo de archivo de datos para :download:`loan_es.mzn <examples/loan_es.mzn>` (:download:`loan3_es.dzn <examples/loan3_es.dzn>`)
509
510
511.. defblock:: Operadores de Coma Flotante
512
513 .. index:
514 single: operator; float
515 single: +
516 single: -
517 single: *
518 single: /
519 single: abs
520 single: sqrt
521 single: ln
522 single: log2
523 single: log10
524 single: exp
525 single: sin
526 single: cos
527 single: tan
528 single: asin
529 single: acos
530 single: atan
531 single: sinh
532 single: cosh
533 single: tanh
534 single: asinh
535 single: acosh
536 single: atanh
537 single: pow
538
539 MiniZinc proporciona los siguiente operadores estándar aritméticos de punto flotante:
540 adición (``+``),
541 subtracción (``-``),
542 multiplicación (``*``)
543 and floating point division (``/``).
544 and floating point division ``+`` y ``-`` as unary operators.
545
546 MiniZinc puede coaccionar de forma automática números enteros a los números de punto flotante. Pero para hacer la coerción explícita, la función incorporada
547 :mzn:`int2float` puede ser usada. Obsérvese que una consecuencia de la coerción automática es que una expresión :mzn:`a / b` siempre se considera una división de punto flotante. Si necesita una división entera, asegúrese de usar el operador :mzn:`div`!.
548
549 MiniZinc proporciona además las siguientes funciones de coma flotante:
550 valor absoluto (``abs``),
551 raíz cuadrada (``sqrt``),
552 logaritmo natural (``ln``),
553 logaritmo en base 2 (``log2``),
554 logaritmo en base 10 (``log10``),
555 exponenciación de $e$ (``exp``),
556 seno (``sin``),
557 coseno (``cos``),
558 tangente (``tan``),
559 arcoseno (``asin``),
560 arco-coseno (``acos``),
561 arco-tangente (``atan``),
562 seno hiperbólico (``sinh``),
563 coseno hiperbólico(``cosh``),
564 tangente hiperbólico(``tanh``),
565 arcoseno hiperbólico(``asinh``),
566 arco-coseno hiperbólico(``acosh``),
567 arco-tangente hiperbólico(``atanh``),
568 y potencia (``pow``) que es la única función binaria, el resto son unarios.
569
570 La sintaxis para literales aritméticos es razonablemente estándar. Ejemplo literales flotantes son ``1.05``, ``1.3e-5`` and ``1.3E+5``.
571
572.. \pjs{Should do multiple solutions????}
573
574Estructura básica de un modelo
575------------------------------
576
577Ahora estamos en condiciones de resumir la estructura básica de un modelo MiniZinc. La estructura esta compuesta por varios elementos (*items*), cada uno de los cuales tiene un punto y coma ``;``` al final. Los elementos pueden ocurrir en cualquier orden.
578
579Por ejemplo, los identificadores no necesitan ser declarados antes de ser utilizados.
580
581Hay 8 clases de :index:`elementos <item>`.
582
583- :index:`Include items <item; include>` permiten que el contenido de otro archivo se inserte en el modelo.
584 Estos tienen la forma:
585
586 .. code-block:: minizincdef
587
588 include <filename>;
589
590 en donde, :mzndef:`<filename>` es una cadena literal.
591 Permite que los modelos grandes se dividan en sub-modelos más pequeños y también la inclusión de restricciones definidas en los archivos de la biblioteca.
592 Veremos un ejemplo en :numref:`ex-smm`.
593
594- :index:`Variable declarations <item; variable declaration>` declaran nuevas variables.
595 Estas variables son variables globales y pueden ser referidos a desde cualquier parte del modelo.
596 Las variables pueden ser de dos tipos.
597 Parámetros a los que se asigna un valor fijo en el modelo o en un archivo de datos y variables de decisión cuyo valor se encuentra sólo cuando se resuelve el modelo.
598 Decimos que los parámetros son :index:`fixed` y variables de decisión :index:`unfixed`.
599 A la variable se le puede asignar opcionalmente un valor como parte de la declaración.
600 La forma es:
601
602 .. index:
603 single: expression; type-inst
604 single: par
605 single: var
606
607 .. code-block:: minizincdef
608
609 <type inst expr>: <variable> [ = ] <expression>;
610
611 El :mzndef:`<type-inst expr>` da la instanciación y el tipo de la variable. Estos son uno de los aspectos más complejos de MiniZinc.
612 Las instanciaciones se declaran utilizando :mzn:`par` para parámetros y
613 :mzn:`var` para variables de decisión. Si no hay una declaración de instanciación explícita entonces la variable es un parámetro.
614 El tipo puede ser un tipo base, como :index:`integer o float range <range>` o un arreglo o un conjunto.
615 Los tipos bases son :mzn:`float`,
616 :mzn:`int`,
617 :mzn:`string`,
618 :mzn:`bool`,
619 :mzn:`ann`
620 de los cuales solo
621 :mzn:`float`, :mzn:`int` and :mzn:`bool` puede usarse para variables de decisión.
622 El tipo de base :mzn:`ann` es una :index:`annotation` --
623 Se analiza las anotaciones en :ref:`sec-search`.
624 :index:`Integer range expressions <range; integer>` puede ser utilizado en lugar del tipo :mzn:`int`.
625 Igualmente :index:`float range expressions <range; float>` puede utilizarse en lugar del tipo :mzn:`float`.
626 Éstos se usan típicamente para dar el dominio de una variable de la decisión pero se pueden también utilizar para restringir el rango de un parámetro. Otro uso de las declaraciones de variables es definir :index:`enumerated types`, los cuales se discuten en :ref:`sec-enum`.
627
628- :index:`Assignment items <item; assignment>` asignar un valor a una variable. Tienen la forma:
629
630 .. code-block:: minizincdef
631
632 <variable> = <expression>;
633
634 Los valores se pueden asignar a las variables de decisión, en cuyo caso la asignación es equivalente a la escritura :mzndef:`constraint <variable> = <expression>`.
635
636- :index:`Constraint items <item; constraint>` forman el corazón del modelo. Tienen la forma:
637
638 .. code-block:: minizincdef
639
640 constraint <Boolean expression>;
641
642 Ya hemos visto ejemplos de restricciones simples usando la comparación aritmética y el operador :mzn:`assert` incorporado.
643 En la siguiente sección veremos ejemplos de restricciones más complejas.
644
645- :index:`Solve items <item; solve>` especifique exactamente qué tipo de solución se busca.
646 Como hemos visto, tienen una de las siguientes tres formas:
647
648 .. code-block:: minizincdef
649
650 solve satisfy;
651 solve maximize <arithmetic expression>;
652 solve minimize <arithmetic expression>;
653
654 Se requiere un modelo para tener exactamente un elemento de resolución.
655
656- :index:`Output items <item; output>` son para presentar bien los resultados de la ejecución del modelo.
657 Estas tienen la forma:
658
659 .. code-block:: minizincdef
660
661 output [ <string expression>, ..., <string expression> ];
662
663 Si no hay ningún elemento de salida,
664 por defecto MiniZinc imprimirá los valores de todas las variables de decisión. Estas variables no se les asignará opcionalmente un valor en el formato de los elementos de asignación.
665
666- :index:`Enumerated type declarations <item; enum>`.
667 Se discute eso en :ref:`sec-arrayset` y :ref:`sec-enum`.
668
669- :index:`Predicate, function and test items <item; predicate>` son para definir nuevas restricciones, funciones y pruebas booleanas.
670 Se discute eso en :ref:`sec-predicates`.
671
672- El :index:`annotation item <item; annotation>` se utiliza para definir una nueva anotación. Se discute eso en :ref:`sec-search`.