this repo has no description
1/* Python Interface for MiniZinc constraint modelling 2 * Author: 3 * Tai Tran <tai.tran@student.adelaide.edu.au> 4 * Supervisor: 5 * Guido Tack <guido.tack@monash.edu> 6 */ 7 8#ifndef __MZNSET_H 9#define __MZNSET_H 10 11#include "Object.h" 12 13#include <exception> 14#include <list> 15#include <vector> 16 17#if PY_MAJOR_VERSION >= 3 18#define Py_TPFLAGS_HAVE_ITER 0 19#endif 20 21using namespace std; 22using namespace MiniZinc; 23 24struct MznRange { 25 long long min; 26 long long max; 27 MznRange(long long min, long long max) : min(min), max(max) {} 28}; 29 30/* 31 * My custom defined Set 32 * 33 * MznSet_init and MznSet_push take a variable list of arguments: 34 * (item1, item2, ..., itemn) 35 * For each item, it can be either a value or a list/tuple of min and max values: 36 * item? = 1,4 or 5 .... 37 * or item? = [1,10] or [5,6] 38 * or item? = (1,10) or (5,6) 39 * For example, a Set of 1..5, 7, 10..15 can be defined like this: 40 * minizinc_internal.Set( [1,5], 7, [10,15] ) 41 * 42 * The set will automatically merge ranges if it can. 43 * 44 * XXX: should a Set of {1,2,6,35} be written as 1..2, 6, 35 45 * or 1, 2, 6, 35? 46 */ 47 48struct MznSet : MznObject { 49 list<MznRange>* ranges; 50 51 void clear() { ranges->clear(); } 52 53 void push(long long min, long long max); 54 void push(long long v); 55 56 long long min(); 57 long long max(); 58 59 long long size() { return ranges->size(); } 60 bool continuous(); 61 bool contains(long long val); 62 63 // Requires an outer GC Lock 64 Expression* e() { 65 vector<IntSetVal::Range> setRanges; 66 for (list<MznRange>::const_iterator it = ranges->begin(); it != ranges->end(); ++it) { 67 setRanges.push_back(IntSetVal::Range(IntVal(it->min), IntVal(it->max))); 68 } 69 Expression* rhs = new SetLit(Location(), IntSetVal::a(setRanges)); 70 return rhs; 71 } 72}; 73 74enum Mzn_PyContainer_Type { MZN_T_LIST, MZN_T_TUPLE, MZN_T_OTHER }; 75 76inline Mzn_PyContainer_Type Mzn_PyContainer_Check(PyObject* o) { 77 if (PyList_Check(o)) 78 return MZN_T_LIST; 79 else if (PyTuple_Check(o)) 80 return MZN_T_TUPLE; 81 else 82 return MZN_T_OTHER; 83} 84 85inline Py_ssize_t Mzn_PyContainer_Size(PyObject* o, Mzn_PyContainer_Type t) { 86 switch (t) { 87 case MZN_T_LIST: 88 return PyList_Size(o); 89 case MZN_T_TUPLE: 90 return PyTuple_Size(o); 91 default: 92 return -1; 93 } 94} 95 96inline PyObject* Mzn_PyContainer_GetItem(PyObject* o, Py_ssize_t i, Mzn_PyContainer_Type t) { 97 switch (t) { 98 case MZN_T_LIST: 99 return PyList_GetItem(o, i); 100 case MZN_T_TUPLE: 101 return PyTuple_GetItem(o, i); 102 default: 103 return NULL; 104 } 105} 106 107// Set representation on terminal command 108// XXX: should be redefined as MznSet_str 109static PyObject* MznSet_repr(PyObject* self); 110 111// Push accepts 1 argument, which is exactly like the Set initialization 112static PyObject* MznSet_push(MznSet* self, PyObject* args); 113static PyObject* MznSet_output(MznSet* self); 114static PyObject* MznSet_min(MznSet* self); 115static PyObject* MznSet_max(MznSet* self); 116static PyObject* MznSet_continuous(MznSet* self); 117static PyObject* MznSet_contains(MznSet* self, PyObject* args); 118static PyObject* MznSet_clear(MznSet* self); 119 120static int MznSet_init(MznSet* self, PyObject* args); 121static PyObject* MznSet_new(PyTypeObject* type, PyObject* args, PyObject* kwds); 122static void MznSet_dealloc(MznSet* self); 123static PyObject* MznSet_iter(PyObject* self); 124 125static PyMethodDef MznSet_methods[] = { 126 {"output", (PyCFunction)MznSet_output, METH_NOARGS, "Return all values in the set"}, 127 {"push", (PyCFunction)MznSet_push, METH_VARARGS, "Expand the set"}, 128 {"min", (PyCFunction)MznSet_min, METH_NOARGS, "Lower bound of the set"}, 129 {"max", (PyCFunction)MznSet_max, METH_NOARGS, "Upper bound of the set"}, 130 {"continuous", (PyCFunction)MznSet_continuous, METH_NOARGS, 131 "Check whether the set is continous"}, 132 {"contains", (PyCFunction)MznSet_contains, METH_VARARGS, 133 "Check whether a python value is in the Set"}, 134 {"clear", (PyCFunction)MznSet_clear, METH_NOARGS, "Clear the set"}, 135 {NULL} /* Sentinel */ 136}; 137 138static PyMemberDef MznSet_members[] = { 139 {NULL} /* Sentinel */ 140}; 141 142static PyTypeObject MznSet_Type = { 143 PyVarObject_HEAD_INIT(NULL, 0) "minizinc.Set", /* tp_name */ 144 sizeof(MznSet), /* tp_basicsize */ 145 0, /* tp_itemsize */ 146 (destructor)MznSet_dealloc, /* tp_dealloc */ 147 0, /* tp_print */ 148 0, /* tp_getattr */ 149 0, /* tp_setattr */ 150 0, /* tp_reserved */ 151 MznSet_repr, /* tp_repr */ 152 0, /* tp_as_number */ 153 0, /* tp_as_sequence */ 154 0, /* tp_as_mapping */ 155 0, /* tp_hash */ 156 0, /* tp_call */ 157 0, /* tp_str */ 158 0, /* tp_getattro */ 159 0, /* tp_setattro */ 160 0, /* tp_as_buffer */ 161 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ 162 "Minizinc Set Object", /* tp_doc */ 163 0, /* tp_traverse */ 164 0, /* tp_clear */ 165 0, /* tp_richcompare */ 166 0, /* tp_weaklistoffset */ 167 MznSet_iter, /* tp_iter */ 168 0, /* tp_iternext */ 169 MznSet_methods, /* tp_methods */ 170 MznSet_members, /* tp_members */ 171 0, /* tp_getset */ 172 &MznObject_Type, /* tp_base */ 173 0, /* tp_dict */ 174 0, /* tp_descr_get */ 175 0, /* tp_descr_set */ 176 0, /* tp_dictoffset */ 177 (initproc)MznSet_init, /* tp_init */ 178 0, /* tp_alloc */ 179 MznSet_new, /* tp_new */ 180}; 181 182struct MznSetIter { 183 // To support python iteration 184 PyObject_HEAD list<MznRange>::const_iterator listIndex; 185 list<MznRange>::const_iterator listBegin; 186 list<MznRange>::const_iterator listEnd; 187 long long currentValue; 188}; 189 190static PyObject* MznSetIter_new(PyTypeObject* type, PyObject* args, PyObject* kwds); 191static void MznSetIter_dealloc(MznSetIter* self); 192static PyObject* MznSetIter_iternext(PyObject* self); 193 194static PyTypeObject MznSetIter_Type = { 195 PyVarObject_HEAD_INIT(NULL, 0) "minizinc.SetIterator", /* tp_name */ 196 sizeof(MznSetIter), /* tp_basicsize */ 197 0, /* tp_itemsize */ 198 (destructor)MznSetIter_dealloc, /* tp_dealloc */ 199 0, /* tp_print */ 200 0, /* tp_getattr */ 201 0, /* tp_setattr */ 202 0, /* tp_reserved */ 203 0, /* tp_repr */ 204 0, /* tp_as_number */ 205 0, /* tp_as_sequence */ 206 0, /* tp_as_mapping */ 207 0, /* tp_hash */ 208 0, /* tp_call */ 209 0, /* tp_str */ 210 0, /* tp_getattro */ 211 0, /* tp_setattro */ 212 0, /* tp_as_buffer */ 213 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ 214 "Minizinc Set Iterator", /* tp_doc */ 215 0, /* tp_traverse */ 216 0, /* tp_clear */ 217 0, /* tp_richcompare */ 218 0, /* tp_weaklistoffset */ 219 PyObject_SelfIter, /* tp_iter */ 220 (iternextfunc)MznSetIter_iternext, /* tp_iternext */ 221 0, /* tp_methods */ 222 0, /* tp_members */ 223 0, /*MznModel_getseters, /* tp_getset */ 224 0, /* tp_base */ 225 0, /* tp_dict */ 226 0, /* tp_descr_get */ 227 0, /* tp_descr_set */ 228 0, /* tp_dictoffset */ 229 0, /* tp_init */ 230 0, /* tp_alloc */ 231 0, /* tp_new */ 232}; 233 234#endif