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
8// This header must be included above all other files
9
10#ifndef __GLOBAL_H
11#define __GLOBAL_H
12
13#include <Python.h>
14
15#if PY_MAJOR_VERSION < 3
16#define PyUnicode_Check PyString_Check
17#define PyUnicode_AsUTF8 PyString_AS_STRING
18#define PyUnicode_FromString PyString_FromString
19#define PyUnicode_Type PyString_Type
20#endif
21
22#include <minizinc/builtins.hh>
23#include <minizinc/copy.hh>
24#include <minizinc/eval_par.hh>
25#include <minizinc/file_utils.hh>
26#include <minizinc/flatten.hh>
27#include <minizinc/model.hh>
28#include <minizinc/optimize.hh>
29#include <minizinc/parser.hh>
30#include <minizinc/prettyprinter.hh>
31#include <minizinc/solvers/gecode_solverinstance.hh>
32#include <minizinc/typecheck.hh>
33
34#include "structmember.h"
35
36#include <algorithm>
37#include <cstdio>
38#include <cstdlib>
39#include <iostream>
40#include <limits.h>
41#include <list>
42#include <stdexcept>
43#include <stdlib.h>
44#include <string.h>
45#include <typeinfo>
46#include <unistd.h>
47
48// These two files are included at the end of the header
49//#include "Object.h"
50//#include "Set.h"
51
52using namespace std;
53using namespace MiniZinc;
54
55static PyObject* MznModel_new_error;
56static PyObject* MznModel_init_error;
57static PyObject* MznModel_solve_error;
58static PyObject* MznModel_load_error;
59static PyObject* MznModel_loadFromString_error;
60static PyObject* MznModel_solve_warning;
61static PyObject* MznVariable_init_error;
62static PyObject* MznSet_error;
63
64// Macro that combines snprintf and PyErr_SetString into one.
65// First argument is PyExc_*Error, Second argument is like ordinary printf function
66#define MZN_PYERR_SET_STRING(py_type_error, ...) \
67 do { \
68 char buffer[150]; \
69 snprintf(buffer, 150, __VA_ARGS__); \
70 PyErr_SetString(py_type_error, buffer); \
71 } while (0)
72
73// Converts C++ long long to appropriate Python integer type
74inline PyObject* c_to_py_number(long long);
75// Converts Python integer type to C++ value, returns -1 if error occurred
76inline long long py_to_c_number(PyObject*);
77// Converts Python integer type to C++ value, set int* to -1 or 1 if overflown, returns -1 if other
78// errors occurred
79inline long long py_to_c_number(PyObject*, int*);
80
81// Nicely presenting the type, for example: set of int or array of [int, int]
82string typePresentation(const Type& type);
83
84// For internal use, only compare TypeInst, BaseType, SetType
85bool compareType(const Type& type1, const Type& type2);
86
87// Converts a minizinc expression of dim()==0 to python value.
88// Note 1: e = vd->e(), type = vd->type()
89// Note 2: e must be not NULL
90inline PyObject* one_dim_minizinc_to_python(Expression* e, const Type& type);
91
92// Convert minizinc expression to python value, return a Python list if vd is an array
93PyObject* minizinc_to_python(VarDecl* vd);
94
95/*
96 * Description: Helper function for python_to_minizinc
97 * converts a python value (not an array) to minizinc expression
98 * also returns the type of that value
99 * Parameters: A python value - pvalue
100 * A minizinc BaseType code
101 * Note: If code == Type::BT_UNKNOWN, it will be changed to the corresponding type of pvalue
102 * If code is initialized to specific type, an error will be thrown if type mismatched
103 * Accepted code type:
104 * - Type::BT_UNKNOWN: Unknown type, will be changed later
105 * - Type::BT_INT
106 * - Type::BT_FLOAT
107 * - Type::BT_STRING
108 * - Type::BT_BOOL
109 * Note 2: Need an outer GCLock for this to work
110 */
111inline Expression* one_dim_python_to_minizinc(PyObject* pvalue, Type::BaseType& code);
112
113/*
114 * Description: Converts a python value to minizinc expression
115 * also returns the type of python value
116 * and the dimension list if it is an array
117 * Return: MiniZinc expression, NULL if error occurred
118 *
119 * Note 1: If you parse a list of MiniZinc Object, remember to parse the object only, not its
120 *wrapper class For current implementation, the python wrapper class must be replaced with a call to
121 * minizinc_internal.Id(wrapper.name) (remember to wrap this function with lock and
122 *unlock()) Note 2: Need an outer GCLock for this to work Note 3: if dimList is empty, any array
123 *created by this function will have its index start from 0 else, the array created will have the
124 *dimension correspondingly to dimList, and it will complain if dimension sizes mismatched
125 */
126Expression* python_to_minizinc(PyObject* pvalue, Type& type, vector<pair<int, int> >& dimList);
127
128/*
129 * Used only when importing model from MiniZinc file
130 * Return: MiniZinc expression, NULL if error occurred
131 * Note: Need an outer GCLock
132 */
133Expression* python_to_minizinc(PyObject* pvalue, const ASTExprVec<TypeInst>& ranges);
134
135/*
136 * A Python dimension list is like this
137 * [ [1,5], [2,5], [3,5] ]
138 * (1st dimension)
139 * (2nd dimension)
140 * (3rd dimension)
141 *
142 * This function converts such dimension list to minizinc ranges list
143 * [ <1..5>, <2..5>, <3..5> ]
144 *
145 * Returns: If error, return empty vector, also set errorOccurred to 1
146 * Else, return a vector of MiniZinc dimension range
147 */
148vector<TypeInst*> pydim_to_minizinc_ranges(PyObject* pydim);
149
150// Helper functions
151// XXX: change the function name to a more meaningful name later
152// starting layer should be 0
153/* converts a python array(list) to:
154 dimensions: an array holding the size of each dimension
155 simpleArray: a 1d-array of Python value
156 return 0 if success, -1 if it is an incomplete array
157 ( incomplete array example:
158 X X X X X X
159 X X X X X
160 X X X X X X
161 X X X X X X
162 )
163*/
164int getList(PyObject* value, vector<Py_ssize_t>& dimensions, vector<PyObject*>& simpleArray,
165 const int layer);
166
167inline bool PyObject_ExactTypeCheck(PyObject* ob, PyTypeObject* type) {
168 return Py_TYPE(ob) == type;
169}
170
171#include "Object.h"
172#include "Set.h"
173
174#endif