Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
9.5 kB · 234 lines
C
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234/* Python Interface for MiniZinc constraint modelling * Author: * Tai Tran <tai.tran@student.adelaide.edu.au> * Supervisor: * Guido Tack <guido.tack@monash.edu> */
#ifndef __MZNSET_H#define __MZNSET_H
#include "Object.h"
#include <exception>#include <list>#include <vector>
#if PY_MAJOR_VERSION >= 3#define Py_TPFLAGS_HAVE_ITER 0#endif
using namespace std;using namespace MiniZinc;
struct MznRange { long long min; long long max; MznRange(long long min, long long max) : min(min), max(max) {}};
/* * My custom defined Set * * MznSet_init and MznSet_push take a variable list of arguments: * (item1, item2, ..., itemn) * For each item, it can be either a value or a list/tuple of min and max values: * item? = 1,4 or 5 .... * or item? = [1,10] or [5,6] * or item? = (1,10) or (5,6) * For example, a Set of 1..5, 7, 10..15 can be defined like this: * minizinc_internal.Set( [1,5], 7, [10,15] ) * * The set will automatically merge ranges if it can. * * XXX: should a Set of {1,2,6,35} be written as 1..2, 6, 35 * or 1, 2, 6, 35? */
struct MznSet : MznObject { list<MznRange>* ranges;
void clear() { ranges->clear(); }
void push(long long min, long long max); void push(long long v);
long long min(); long long max();
long long size() { return ranges->size(); } bool continuous(); bool contains(long long val);
// Requires an outer GC Lock Expression* e() { vector<IntSetVal::Range> setRanges; for (list<MznRange>::const_iterator it = ranges->begin(); it != ranges->end(); ++it) { setRanges.push_back(IntSetVal::Range(IntVal(it->min), IntVal(it->max))); } Expression* rhs = new SetLit(Location(), IntSetVal::a(setRanges)); return rhs; }};
enum Mzn_PyContainer_Type { MZN_T_LIST, MZN_T_TUPLE, MZN_T_OTHER };
inline Mzn_PyContainer_Type Mzn_PyContainer_Check(PyObject* o) { if (PyList_Check(o)) return MZN_T_LIST; else if (PyTuple_Check(o)) return MZN_T_TUPLE; else return MZN_T_OTHER;}
inline Py_ssize_t Mzn_PyContainer_Size(PyObject* o, Mzn_PyContainer_Type t) { switch (t) { case MZN_T_LIST: return PyList_Size(o); case MZN_T_TUPLE: return PyTuple_Size(o); default: return -1; }}
inline PyObject* Mzn_PyContainer_GetItem(PyObject* o, Py_ssize_t i, Mzn_PyContainer_Type t) { switch (t) { case MZN_T_LIST: return PyList_GetItem(o, i); case MZN_T_TUPLE: return PyTuple_GetItem(o, i); default: return NULL; }}
// Set representation on terminal command// XXX: should be redefined as MznSet_strstatic PyObject* MznSet_repr(PyObject* self);
// Push accepts 1 argument, which is exactly like the Set initializationstatic PyObject* MznSet_push(MznSet* self, PyObject* args);static PyObject* MznSet_output(MznSet* self);static PyObject* MznSet_min(MznSet* self);static PyObject* MznSet_max(MznSet* self);static PyObject* MznSet_continuous(MznSet* self);static PyObject* MznSet_contains(MznSet* self, PyObject* args);static PyObject* MznSet_clear(MznSet* self);
static int MznSet_init(MznSet* self, PyObject* args);static PyObject* MznSet_new(PyTypeObject* type, PyObject* args, PyObject* kwds);static void MznSet_dealloc(MznSet* self);static PyObject* MznSet_iter(PyObject* self);
static PyMethodDef MznSet_methods[] = { {"output", (PyCFunction)MznSet_output, METH_NOARGS, "Return all values in the set"}, {"push", (PyCFunction)MznSet_push, METH_VARARGS, "Expand the set"}, {"min", (PyCFunction)MznSet_min, METH_NOARGS, "Lower bound of the set"}, {"max", (PyCFunction)MznSet_max, METH_NOARGS, "Upper bound of the set"}, {"continuous", (PyCFunction)MznSet_continuous, METH_NOARGS, "Check whether the set is continous"}, {"contains", (PyCFunction)MznSet_contains, METH_VARARGS, "Check whether a python value is in the Set"}, {"clear", (PyCFunction)MznSet_clear, METH_NOARGS, "Clear the set"}, {NULL} /* Sentinel */};
static PyMemberDef MznSet_members[] = { {NULL} /* Sentinel */};
static PyTypeObject MznSet_Type = { PyVarObject_HEAD_INIT(NULL, 0) "minizinc.Set", /* tp_name */ sizeof(MznSet), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)MznSet_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ MznSet_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ "Minizinc Set Object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ MznSet_iter, /* tp_iter */ 0, /* tp_iternext */ MznSet_methods, /* tp_methods */ MznSet_members, /* tp_members */ 0, /* tp_getset */ &MznObject_Type, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)MznSet_init, /* tp_init */ 0, /* tp_alloc */ MznSet_new, /* tp_new */};
struct MznSetIter { // To support python iteration PyObject_HEAD list<MznRange>::const_iterator listIndex; list<MznRange>::const_iterator listBegin; list<MznRange>::const_iterator listEnd; long long currentValue;};
static PyObject* MznSetIter_new(PyTypeObject* type, PyObject* args, PyObject* kwds);static void MznSetIter_dealloc(MznSetIter* self);static PyObject* MznSetIter_iternext(PyObject* self);
static PyTypeObject MznSetIter_Type = { PyVarObject_HEAD_INIT(NULL, 0) "minizinc.SetIterator", /* tp_name */ sizeof(MznSetIter), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)MznSetIter_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ "Minizinc Set Iterator", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)MznSetIter_iternext, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /*MznModel_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */};
#endif