00001
00002
00015
00016
00017 #ifndef polybori_embed_h_
00018 #define polybori_embed_h_
00019
00020
00021 #include <polybori/polybori.h>
00022
00023 #include <boost/python.hpp>
00024 #include <boost/python/stl_iterator.hpp>
00025
00026 #include <string>
00027 #include <iostream>
00028 #include <vector>
00029 #include <list>
00030 #include <set>
00031
00032
00033 #ifndef PBORI_PYTHONPATH
00034 #define PBORI_PYTHONPATH "."
00035 #endif
00036
00037 BEGIN_NAMESPACE_PBORI
00038
00040 using boost::python::str;
00041 using boost::python::import;
00042 using boost::python::handle;
00043 using boost::python::borrowed;
00044 using boost::python::extract;
00045 using boost::python::stl_input_iterator;
00046 using boost::python::error_already_set;
00047
00048
00050 typedef BoolePolyRing Ring;
00051 typedef BoolePolynomial Polynomial;
00052 typedef BooleVariable Variable;
00053 typedef BooleMonomial Monomial;
00054
00056 enum order_codes {
00057 lp = PBORI::COrderEnums::lp,
00058 dlex = PBORI::COrderEnums::dlex,
00059 dp_asc = PBORI::COrderEnums::dp_asc,
00060 block_dlex = PBORI::COrderEnums::block_dlex,
00061 block_dp_asc = PBORI::COrderEnums::block_dp_asc
00062 };
00063
00071 class Interpreter {
00072 public:
00073
00075 ~Interpreter() { if(m_owns_python) Py_Finalize(); }
00076
00079 static void init() { instance(); }
00080
00082 static boost::python::object& globals() { return instance().m_globals; }
00083
00084 private:
00086 Interpreter():
00087 m_owns_python(false), m_globals() {
00088 if (!Py_IsInitialized()) init_python();
00089 set_python_defaults();
00090 }
00091
00094 static Interpreter& instance() {
00095 static Interpreter init_interpreter;
00096 return init_interpreter;
00097 }
00098
00100 void init_python() {
00101 Py_Initialize();
00102 m_owns_python = true;
00103 }
00104
00106 void set_python_defaults() {
00107
00108 const char* argv = "";
00109 PySys_SetArgv(1, (char**)&argv);
00110 import("sys").attr("path").attr("insert")(0, PBORI_PYTHONPATH);
00111 PyRun_SimpleString("from polybori.frontend import *");
00112
00113 m_globals = import("__main__").attr("__dict__");
00114 boost::python::object start = boost::python::eval("polybori_start", m_globals, m_globals);
00115 start(m_globals);
00116 }
00117
00119 bool m_owns_python;
00120
00122 boost::python::object m_globals;
00123 };
00124
00125 template <class Type>
00126 class DerefProxy {
00127 typedef DerefProxy self;
00128 public:
00129
00130 DerefProxy(const Type& val): m_val(val) {}
00131
00132 DerefProxy<self> operator*() {
00133 return *this;
00134 }
00135 const Type& get() const{ return m_val; }
00136
00137 private:
00138 const Type& m_val;
00139 };
00140
00144 class dict:
00145 public boost::python::dict {
00146 typedef dict self;
00147 typedef boost::python::dict base;
00148
00149 public:
00151 template <class Type>
00152 dict(const Type& obj): base(obj) {}
00153
00155 dict(): base() {}
00156
00158 DerefProxy<self> operator*() {
00159 return *this;
00160 }
00161 };
00162
00166 class tuple:
00167 public boost::python::tuple {
00168 typedef tuple self;
00169 typedef boost::python::tuple base;
00170
00171 public:
00173 template <class Type>
00174 tuple(const Type& obj): base(obj) {}
00175
00177 tuple(): base() {}
00178
00180 DerefProxy<self> operator*() {
00181 return *this;
00182 }
00183 };
00184
00188 class object:
00189 public boost::python::object {
00190
00191 typedef object self;
00192 typedef boost::python::object base;
00193
00194 public:
00196 template <class Type>
00197 object(const Type& obj): base(obj) {}
00198
00200 object(): base() {}
00201
00203 self
00204 operator()(const DerefProxy<tuple>& args,
00205 const DerefProxy<DerefProxy<dict> >& kwds) const {
00206 return object(handle<>(borrowed(PyObject_Call(base::ptr(), args.get().ptr(),
00207 kwds.get().get().ptr()))));
00208 }
00210
00211 template <class Type>
00212 self operator()(const Type& arg) const {
00213 return static_cast<const boost::python::object&>(*this)(arg);
00214 }
00215 template <class Type1, class Type2>
00216 self operator()(const Type1& arg1, const Type2& arg2) const {
00217 return static_cast<const boost::python::object&>(*this)(arg1, arg2);
00218 }
00219 template <class Type1, class Type2, class Type3>
00220 self operator()(const Type1& arg1, const Type2& arg2, const Type3& arg3) const {
00221 return static_cast<const boost::python::object&>(*this)(arg1, arg2, arg3);
00222 }
00223 template <class Type1, class Type2, class Type3, class Type4>
00224 self operator()(const Type1& arg1, const Type2& arg2, const Type3& arg3,
00225 const Type4& arg4) const {
00226 return static_cast<const boost::python::object&>(*this)(arg1, arg2, arg3,
00227 arg4);
00228 }
00230
00232
00233 template <class Type>
00234 self operator()(const DerefProxy<DerefProxy<dict> >& kwds) const {
00235 return self::operator()(DerefProxy<tuple>(boost::python::make_tuple()), kwds);
00236 }
00237 template <class Type>
00238 self operator()(const Type& arg,
00239 const DerefProxy<DerefProxy<dict> >& kwds) const {
00240 return self::operator()(DerefProxy<tuple>(boost::python::make_tuple(arg)), kwds);
00241 }
00242 template <class Type1, class Type2>
00243 self operator()(const Type1& arg1, const Type2& arg2,
00244 const DerefProxy<DerefProxy<dict> >& kwds) const {
00245 return self::operator()(DerefProxy<tuple>(boost::python::make_tuple(arg1, arg2)), kwds);
00246 }
00247 template <class Type1, class Type2, class Type3>
00248 self operator()(const Type1& arg1, const Type2& arg2, const Type3& arg3,
00249 const DerefProxy<DerefProxy<dict> >& kwds) const {
00250 return self::operator()(DerefProxy<tuple>(boost::python::make_tuple(arg1, arg2, arg3)), kwds);
00251 }
00252 template <class Type1, class Type2, class Type3, class Type4>
00253 self operator()(const Type1& arg1, const Type2& arg2, const Type3& arg3,
00254 const Type4& arg4, const DerefProxy<DerefProxy<dict> >& kwds) const {
00255 return self::operator()(DerefProxy<tuple>(boost::python::make_tuple(arg1, arg2, arg3,
00256 arg4)), kwds);
00257 }
00259
00261
00262 operator bool() const {
00263 return extract<bool>(*this);
00264 }
00265 operator int() const {
00266 return extract<int>(*this);
00267 }
00268 operator long() const {
00269 return extract<long>(*this);
00270 }
00271 operator std::string() const {
00272 return extract<std::string>(*this);
00273 }
00274
00275 operator const Ring&() const {
00276 return extract<const Ring&>(*this);
00277 }
00278 operator Polynomial() const {
00279 return extract<Polynomial>(*this);
00280 }
00281 operator Monomial() const {
00282 return extract<Monomial>(*this);
00283 }
00284 operator const Variable&() const {
00285 return extract<const Variable&>(*this);
00286 }
00287 operator BooleSet() const {
00288 return extract<BooleSet>(*this);
00289 }
00290 template <class Type>
00291 operator std::vector<Type>() const {
00292 stl_input_iterator<self> begin(*this), end;
00293 return std::vector<Type>(begin, end);
00294 }
00295 template <class Type>
00296 operator std::list<Type>() const {
00297 stl_input_iterator<self> begin(*this), end;
00298 return std::list<Type>(begin, end);
00299 }
00300 template <class Type>
00301 operator std::set<Type>() const {
00302 stl_input_iterator<self> begin(*this), end;
00303 return std::set<Type>(begin, end);
00304 }
00306 };
00307
00308
00309 inline object
00310 eval(str expression) {
00311
00312 try {
00313 return boost::python::eval(expression,
00314 Interpreter::globals(),
00315 Interpreter::globals());
00316 }
00317 catch( error_already_set ) {
00318 PyErr_Print();
00319 }
00320 return object();
00321 }
00322
00323 inline object
00324 exec(str code) {
00325 try {
00326 return boost::python::exec(code,
00327 Interpreter::globals(),
00328 Interpreter::globals());
00329 }
00330 catch( error_already_set ) {
00331 PyErr_Print();
00332 }
00333 return object();
00334 }
00335
00336 inline object
00337 exec_file(str filename) {
00338 try {
00339 return boost::python::exec_file(filename,
00340 Interpreter::globals(),
00341 Interpreter::globals());
00342 }
00343 catch( error_already_set ) {
00344 PyErr_Print();
00345 }
00346 return object();
00347 }
00348
00349
00350 inline void
00351 run (const char* code) {
00352 PyRun_SimpleString(code);
00353 }
00354
00355
00356 END_NAMESPACE_PBORI
00357
00358
00359 namespace boost { namespace python { namespace converter {
00360 template <>
00361 struct object_manager_traits<PBORI::dict>:
00362 object_manager_traits<boost::python::dict> {};
00363
00364 template <>
00365 struct object_manager_traits<PBORI::tuple>:
00366 object_manager_traits<boost::python::tuple> {};
00367
00368 template <>
00369 struct object_manager_traits<PBORI::object>:
00370 object_manager_traits<boost::python::object> {};
00371
00372 }}}
00373
00374 #define BEGIN_PBORI_EMBED() try { USING_NAMESPACE_PBORI; while(0)
00375 #define END_PBORI_EMBED() } catch(PBORI::error_already_set) { PyErr_Print(); } while(0)
00376
00377 #endif
00378