this repo has no description
1/*
2 * Author:
3 * Tai Tran <tai.tran@student.adelaide.edu.au>
4 * Supervisor:
5 * Guido Tack <guido.tack@monash.edu>
6 */
7#ifndef __MODEL_H
8#define __MODEL_H
9
10#include "global.h"
11
12struct MznModel {
13 PyObject_HEAD Env* _e;
14 Model* _m;
15 vector<string>* includePaths;
16
17 // SolverCode definition is in global.h
18 enum SolverCode { SC_UNKNOWN, SC_GECODE } sc;
19
20 const static SolverCode default_solver = SC_UNKNOWN;
21
22 unsigned long timeLimit;
23 bool loaded;
24
25 MznModel();
26
27 int load(PyObject* args, PyObject* keywds, bool fromFile);
28 int addData(const char* const name, PyObject* value);
29
30 PyObject* set_solver(const char* s);
31 PyObject* solve(PyObject* args, PyObject* kwds);
32};
33
34void MznModelDestructor(PyObject* o);
35static PyObject* MznModel_new(PyTypeObject* type, PyObject* args, PyObject* kwds);
36static int MznModel_init(MznModel* self, PyObject* args);
37static void MznModel_dealloc(MznModel* self);
38
39/************************************************************
40 Groups of function general functions
41 ************************************************************/
42/** Function arguments - allow keywords
43 dict: dictionary of name - value, used when loading from a minizinc file only
44 key: name of the value to be assigned
45 value: value to be assigned
46 solver: solver name
47 if solver_name == '', do nothing
48 else, solve the model using specified solver
49 time: time limit
50 if time_limit != 0, set new time limit
51 */
52static PyObject* MznModel_solve(MznModel* self, PyObject* args, PyObject* kwds);
53
54static PyObject* MznModel_set_time_limit(MznModel* self, PyObject* args);
55static PyObject* MznModel_set_solver(MznModel* self, PyObject* args);
56
57/************************************************************
58 Groups of function functions to interact with MiniZinc files
59 ************************************************************/
60static PyObject* MznModel_load(MznModel* self, PyObject* args, PyObject* keywds);
61static PyObject* MznModel_load_from_string(MznModel* self, PyObject* args, PyObject* keywds);
62// Take in a name and a Python value, add that data to the current model
63static PyObject* MznModel_addData(MznModel* self, PyObject* args);
64
65/***************************************************************
66 Groups of function functions to interact with Python Interface
67 ***************************************************************/
68/* Function: MznModel_Declaration
69 * Description: Take in a tuple of arguments, create a Variable in the Minizinc Model self
70 * Arguments:
71 * 1: name, TypeId, dimension vector, lower bound, upper bound
72 * name: string
73 * TypeId: see enum TypeId below
74 * dimension vector: empty if Variable is not an array
75 * holds value if it is an array
76 * Syntax: vector<pair<int, int> >, called dimList
77 * - dimList[i] is the lower bound and upper bound of dimension i
78 * - for example:
79 * dimList[0] = <1,5>
80 * dimList[1] = <2,4>
81 * dimList[2] = <0,5>
82 * means a 3d array [1..5,2..4,0..5]
83 * lower bound: can be MiniZinc Set, int or float
84 * upper bound: None if lower bound is MiniZinc Set,
85 * type(lower bound) otherwise
86 *
87 * 2: name, python value
88 * python value: Create a variable based on the existing python value
89 * Return:
90 * Id of the declared variable
91 * Note 1:
92 * Don't reuse this declaration if the model with this declaration has been destroyed
93 * Note 2:
94 * Python Interface holds the responsibility of checking which type of value is declared.
95 */
96static PyObject* MznModel_Declaration(MznModel* self, PyObject* args);
97
98/* Function: MznModel_Constraint
99 * Description: Take in a Python boolean or MiniZinc Expression, add it to the MiniZinc Model self
100 * Return:
101 * None
102 * Note: It is the Python Interface responsibility to check if parsed argument is of type bool or
103 * not
104 */
105static PyObject* MznModel_Constraint(MznModel* self, PyObject* args);
106
107/* Function: MznModel_SolveItem
108 * Description: Add a solve item into the model
109 * Arguments:
110 * Arg1: Solve Type: 0 ~ sat, 1 ~ min, 2 ~ max
111 * Arg2 (opt): Annotation
112 * Arg3 (opt): Expression to be minimize / maximize if Arg1 != 0
113 * Return:
114 * None
115 * Note:
116 * Arg2 accepts all MiniZinc expression, but the Python Interface should ensures that
117 * Arg2 is an expression of MiniZinc Annotation.
118 */
119static PyObject* MznModel_SolveItem(MznModel* self, PyObject* args);
120
121// Returns an exact copy of the current model
122static PyObject* MznModel_copy(MznModel* self);
123// Print the MiniZinc representation of the model
124static PyObject* MznModel_debugprint(MznModel* self);
125
126// Declare all the functions
127static PyMethodDef MznModel_methods[] = {
128 {"load", (PyCFunction)MznModel_load, METH_KEYWORDS, "Load MiniZinc model from MiniZinc file"},
129 {"load_from_string", (PyCFunction)MznModel_load_from_string, METH_KEYWORDS,
130 "Load MiniZinc model from standard input"},
131 {"addData", (PyCFunction)MznModel_addData, METH_VARARGS, "Add data to a MiniZinc model"},
132 {"solve", (PyCFunction)MznModel_solve, METH_VARARGS | METH_KEYWORDS,
133 "Solve a loaded MiniZinc model"},
134 {"set_time_limit", (PyCFunction)MznModel_set_time_limit, METH_VARARGS,
135 "Limit the execution time of the model"},
136 {"set_solver", (PyCFunction)MznModel_set_solver, METH_VARARGS,
137 "Choose which model will be used to solve the model"},
138 {"Declaration", (PyCFunction)MznModel_Declaration, METH_VARARGS,
139 "Add a variable into the model"},
140 {"Constraint", (PyCFunction)MznModel_Constraint, METH_VARARGS,
141 "Add a constraint into the model"},
142 {"SolveItem", (PyCFunction)MznModel_SolveItem, METH_VARARGS, "Add a solve item into the model"},
143
144 {"copy", (PyCFunction)MznModel_copy, METH_NOARGS, "Returns a copy of current model"},
145 {"debugprint", (PyCFunction)MznModel_debugprint, METH_NOARGS,
146 "Print the MiniZinc representation of the current model"},
147 {NULL} /* Sentinel */
148};
149
150static PyMemberDef MznModel_members[] = {
151 {NULL} /* Sentinel */
152};
153
154static PyTypeObject MznModel_Type = {
155 PyVarObject_HEAD_INIT(NULL, 0) "minizinc_internal.Model", /* tp_name */
156 sizeof(MznModel), /* tp_basicsize */
157 0, /* tp_itemsize */
158 (destructor)MznModel_dealloc, /* tp_dealloc */
159 0, /* tp_print */
160 0, /* tp_getattr */
161 0, /* tp_setattr */
162 0, /* tp_reserved */
163 0, /* tp_repr */
164 0, /* tp_as_number */
165 0, /* tp_as_sequence */
166 0, /* tp_as_mapping */
167 0, /* tp_hash */
168 0, /* tp_call */
169 0, /* tp_str */
170 0, /* tp_getattro */
171 0, /* tp_setattro */
172 0, /* tp_as_buffer */
173 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
174 "Minizinc Model", /* tp_doc */
175 0, /* tp_traverse */
176 0, /* tp_clear */
177 0, /* tp_richcompare */
178 0, /* tp_weaklistoffset */
179 0, /* tp_iter */
180 0, /* tp_iternext */
181 MznModel_methods, /* tp_methods */
182 MznModel_members, /* tp_members */
183 0, /* tp_getset */
184 0, /* tp_base */
185 0, /* tp_dict */
186 0, /* tp_descr_get */
187 0, /* tp_descr_set */
188 0, /* tp_dictoffset */
189 (initproc)MznModel_init, /* tp_init */
190 0, /* tp_alloc */
191 MznModel_new, /* tp_new */
192};
193
194#endif