My Project
interpreter_support.cc
Go to the documentation of this file.
1 #include "kernel/mod2.h"
2 #ifdef HAVE_PYTHON
3 #include <sstream>
4 #include <boost/python.hpp>
5 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
6 #include "Singular/subexpr.h"
7 #include "Poly.h"
8 #include "Ideal.h"
9 #include "kernel/structs.h"
10 #include "Singular/lists.h"
11 #include "Singular/ipid.h"
12 #include "Singular/ipshell.h"
13 #include "coeffs/numbers.h"
14 
15 #include "Singular/ipid.h"
16 #include "Singular/ipshell.h"
17 #include "polys/matpol.h"
18 #include "ring_wrap.h"
19 #include "intvec_wrap.h"
20 #include "poly_wrap.h"
22 using namespace boost::python;
23 using boost::python::extract;
24 static void free_leftv(leftv args)
25 {
26  args->CleanUp();
27  omFreeBin(args, sleftv_bin);
28 }
29 
30 #if BOOST_VERSION < 106500 /* 1.65 */
31 typedef typename boost::python::numeric::array NumpyArrayType;
32 #else
33 #include <boost/python/numpy.hpp>
34 typedef typename boost::python::numpy::ndarray NumpyArrayType;
35 #endif
36 
38 {
39  object o=f.attr("shape");
40  object o1=o[0];
41  object o2=o[1];
42  int l1=extract<int>(o1);
43  int l2=extract<int>(o2);
44  matrix m=mpNew(l1,l2);
45  for(int i=0;i<l1;i++)
46  {
47  for(int j=0;j<l2;j++)
48  {
49  Poly& x = boost::python::extract<Poly&>(f[boost::python::make_tuple(i,j)]);
50  poly p=x.as_poly();
51  MATELEM(m,i+1,j+1)=p;
52  }
53  }
54  return m;
55 }
56 bool is_builtin(const char* name)
57 {
58  int cmd_n=-1;
59  IsCmd(name,cmd_n);
60  return (cmd_n!=-1);
61 }
62 class arg_list
63 {
64  public:
67  {
68  args=(leftv) NULL;
69  }
71  {
72  if (args!=NULL)
73  {
74  args->CleanUp();
75  omFreeBin(args, sleftv_bin);
76  }
77  }
79  {
80  assume(args!=NULL);
81  leftv res=args;
82  args=args->next;
83  res->next=NULL;
84  return res;
85  }
86  int length()
87  {
88  leftv v=args;
89  int l=0;
90  while(v!=NULL)
91  {
92  l++;
93  v=v->next;
94  }
95  return l;
96  }
97  void appendPoly(const Poly& p)
98  {
99  leftv v=initArg();
100  v->data=p.as_poly();
101  v->rtyp=POLY_CMD;
102  internal_append(v);
103  }
104  void appendIdeal(const Ideal& p)
105  {
106  leftv v=initArg();
107  v->data=p.as_ideal();
108  v->rtyp=IDEAL_CMD;
109  internal_append(v);
110  }
111  void appendModule(const Module& p)
112  {
113  leftv v=initArg();
114  v->data=p.as_module();
115  v->rtyp=MODUL_CMD;
116  internal_append(v);
117  }
118  void appendint(int p)
119  {
120  leftv v=initArg();
121  v->data=(void*)((long)p);
122  v->rtyp=INT_CMD;
123  internal_append(v);
124  }
125  void appendNumber(const Number& p)
126  {
127  leftv v=initArg();
128  v->data=(void*) p.as_number();
129  v->rtyp=NUMBER_CMD;
130  internal_append(v);
131  }
132  void appendVector(const Vector& p)
133  {
134  leftv v=initArg();
135  v->data=p.as_poly();
136  v->rtyp=VECTOR_CMD;
137  internal_append(v);
138  }
140  {
141  leftv v=initArg();
143  v->data=m;
144  v->rtyp=MATRIX_CMD;
145  internal_append(v);
146  }
147  void appendString(const char* s)
148  {
149  leftv v=initArg();
150  v->data=omStrDup(s);
151  v->rtyp=STRING_CMD;
152  internal_append(v);
153  }
154  void appendRing(const Ring& r)
155  {
156  leftv v=initArg();
157  v->data=r.pimpl.get();
158  r.pimpl->ref++;
159  v->rtyp=RING_CMD;
160  internal_append(v);
161  }
163  {
164  int n=length();
166  res->Init(n);
167  for(int i=0;i<n;i++)
168  {
169  leftv iv=pop_front();
170  //swap the content
171  memcpy(&res->m[i],iv,sizeof(sleftv));
172  //iv->Init();
173  omFreeBin(iv, sleftv_bin);
174  }
175  return res;
176  }
178  {
179  leftv v=initArg();
180  v->data=l.dumpToLists();
181  v->rtyp=LIST_CMD;
182  internal_append(v);
183  }
185  {
186  leftv v=initArg();
187  v->data=iv.allocate_legacy_intvec_copy();
188  v->rtyp=INTVEC_CMD;
189  internal_append(v);
190  }
191 protected:
193  {
195  res->Init();
196  return res;
197  }
199  {
200  if (args!=NULL)
201  {
202  leftv last=args;
203  while(last->next!=NULL)
204  {
205  last=last->next;
206  }
207  last->next=v;
208  }
209  else
210  args=v;
211  }
212 };
213 
215 {
216  public:
219  {
220  this->id=id;
221  }
223  {
224  id=(idhdl) NULL;
225  }
226  bool is_zero()
227  {
228  return id==NULL;
229  }
230  bool id_is_proc()
231  {
232  return (id->typ==PROC_CMD);
233  }
234  bool print_type()
235  {
236  Print("type:%d\n",id->typ);
237  }
238  void writePoly(const Poly& p)
239  {
240  if (id->typ==POLY_CMD)
241  {
242  p_Delete(&id->data.p, currRing);
243  id->data.p=p.as_poly();
244  }
245  }
246  void writeIdeal(const Ideal& p)
247  {
248  if (id->typ==IDEAL_CMD)
249  {
250  id_Delete(&id->data.uideal, currRing);
251  id->data.uideal=p.as_ideal();
252  }
253  }
254  void writeModule(const Module& p)
255  {
256  if (id->typ==MODUL_CMD)
257  {
258  id_Delete(&id->data.uideal, currRing);
259  id->data.uideal=p.as_module();
260  }
261  }
262  void writeint(int p)
263  {
264  if (id->typ==INT_CMD)
265  {
266  id->data.i=p;
267  }
268  }
269  void writeNumber(const Number& p)
270  {
271  if (id->typ==NUMBER_CMD)
272  {
273  n_Delete(&id->data.n, currRing);
274  id->data.n=p.as_number();
275  }
276  }
277  void writeVector(const Vector& p)
278  {
279  if (id->typ==VECTOR_CMD)
280  {
281  p_Delete(&id->data.p, currRing);
282  id->data.p=p.as_poly();
283  }
284  }
286  {
287  if(id->typ=MATRIX_CMD)
288  {
290  id_Delete((ideal*) &id->data.umatrix,currRing);
291  id->data.umatrix=m;
292  }
293  }
294  void writeRing(const Ring& r)
295  {
296  if(id->typ=RING_CMD)
297  {
298  r.pimpl->ref++;
299  ((ring) id->data.uring)->ref--;//FIXME: destruct it
300  ring r2=r.pimpl.get();
301  id->data.uring=r2;
302  }
303  }
304  void writeString(const char* s)
305  {
306  if(id->typ=STRING_CMD)
307  {
308  omFree((ADDRESS) id->data.ustring);
309  id->data.ustring=omStrDup(s);
310  }
311  }
312  void writeIntvec(const Intvec& iv)
313  {
314  if(id->typ=INTVEC_CMD)
315  {
316  delete id->data.iv;
317  id->data.iv=iv.allocate_legacy_intvec_copy();;
318  }
319  }
321  {
322  //warning f gets empty
323  if(id->typ=LIST_CMD)
324  {
325  id->data.l->Clean(currRing);
326  id->data.l=f.dumpToLists();
327  }
328  }
329 };
330 
331 
333 {
334  //using boost::python::numeric::array;
335  using boost::python::self;
336  using boost::python::make_tuple;
337  using boost::python::tuple;
338  using boost::python::object;
339  using boost::python::list;
340 
341  list l;
342  for(int i=1;i<=MATROWS(m);i++)
343  {
344  list row;
345  for(int j=1;j<=MATCOLS(m);j++)
346  {
347  Poly ip(MATELEM(m,i,j),r);//copy it
348  row.append(ip);
349  //a[boost::python::make_tuple(i%2,i%5)]=ip;
350  //a[boost::python::make_tuple(i%2,i%5)]=ip;
351  }
352  l.append(row);
353  }
354  #if BOOST_VERSION <106500
355  //FIXME: should call this only once
356  NumpyArrayType::set_module_and_type("Numeric",
357  "ArrayType"
358  );
359  return NumpyArrayType(l);
360  #else
361  return boost::python::numpy::array(l);
362  #endif
363 }
364 boost::python::object buildPyObjectFromLeftv(leftv v);
365 boost::python::list buildPythonList(lists l, ring r)
366 {
367  using boost::python::list;
368  list res;
369 
370  for(int i=0;i<=l->nr;i++)
371  {
372  leftv lv=&l->m[i];
373  object o=buildPyObjectFromLeftv(lv);
374  res.append(o);
375  }
376  return res;
377 }
378 
379 boost::python::object buildPyObjectFromLeftv(leftv v)
380 {
381  using boost::python::object;
382  switch (v->rtyp)
383  {
384  case INT_CMD:
385  return object((int)((long)v->data));
386  case POLY_CMD:
387  return object(Poly((poly) v->data, currRing));
388  case STRING_CMD:
389  return str((const char*) v->data);
390  case VECTOR_CMD:
391  return object( Vector((poly) v->data, currRing));
392  case IDEAL_CMD:
393  return object(Ideal((ideal) v->data, currRing));
394  case MODUL_CMD:
395  return object(Module((ideal) v->data, currRing));
396  case NUMBER_CMD:
397  return object(Number((number) v->data, currRing));
398  case MATRIX_CMD:
399  return buildPythonMatrix((matrix) v->data,currRing);
400  case LIST_CMD:
401  return buildPythonList((lists) v->data, currRing);
402  case RING_CMD:
403  return object(Ring((ring) v->data));
404  case INTVEC_CMD:
405  return object(Intvec(*(intvec*) v->data));
406 
407  default:
408  return object();
409  }
410 }
411 boost::python::object buildPyObjectFromIdhdl(const idhdl_wrap& id)
412 {
413  using boost::python::object;
414 
415  switch (id.id->typ)
416  {
417  case STRING_CMD:
418  return str((const char*) id.id->data.ustring);
419 
420  case INT_CMD:
421  return object((int)id.id->data.i);
422  case POLY_CMD:
423 
424  return object(Poly((poly) id.id->data.p, currRing));
425  case VECTOR_CMD:
426 
427  return object( Vector((poly) id.id->data.p, currRing));
428  case IDEAL_CMD:
429  //object res;
430 
431  return object(Ideal((ideal) id.id->data.uideal, currRing));
432  case MODUL_CMD:
433  //object res;
434 
435  return object(Module((ideal) id.id->data.uideal, currRing));
436  case NUMBER_CMD:
437 
438  return object(Number((number) id.id->data.n, currRing));
439  case MATRIX_CMD:
440  {
441  return buildPythonMatrix((matrix) id.id->data.umatrix,currRing);
442  }
443  case LIST_CMD:
444  return buildPythonList((lists) id.id->data.l, currRing);
445  case RING_CMD:
446  return object(Ring((ring) id.id->data.uring));
447  case INTVEC_CMD:
448  return object(Intvec(*(intvec*) id.id->data.iv));
449  default:
450  return object();
451  //Py_INCREF(Py_None);
452  //return Py_None;
453  }
454 }
455 
456 boost::python::object call_interpreter_method(const idhdl_wrap& proc, const arg_list& args)
457 {
458  int err=iiMake_proc(proc.id, NULL, args.args);
460 
462 }
463 boost::python::object call_builtin_method_general(const char* name, arg_list& l)
464 {
465  int cmd_n=-1;
466  IsCmd(name,cmd_n);
467 // Py_INCREF(Py_None);
468 
469 // return Py_None;
470  if (cmd_n<0)
471  {
472  return object();
473  }
474  else
475  {
477  res->Init();
478  switch(l.length())
479  {
480  case 1:
481  iiExprArith1(res,l.args,cmd_n);
482  break;
483  case 2:
484  {
485  leftv arg1=l.pop_front();
486  leftv arg2=l.pop_front();
487  iiExprArith2(res,arg1,cmd_n,arg2,TRUE);
488  free_leftv(arg1);
489  free_leftv(arg2);
490  break;
491  }
492  case 3:
493  {
494  leftv arg1=l.pop_front();
495  leftv arg2=l.pop_front();
496  leftv arg3=l.pop_front();
497  iiExprArith3(res,cmd_n,arg1,arg2,arg3);
498  free_leftv(arg1);
499  free_leftv(arg2);
500  free_leftv(arg3);
501  break;
502  }
503  default:
504  iiExprArithM(res, l.args, cmd_n);
505  }
506  boost::python::object real_res=buildPyObjectFromLeftv(res);
507  res->CleanUp();
510  return real_res;
511  //cleanup not to forget
512  }
513 }
515 {
516  idhdl i=iw.id;
517  using boost::python::str;
518  //ring r=p.getRing();
519 
520  std::basic_stringstream<char> s;
521  s<<i;
522  return boost::python::str(s.str());
523 }
524 static idhdl_wrap get_idhdl(const char *n)
525 {
526  //idhdl ggetid(const char *n);
527  return idhdl_wrap(ggetid(n));
528 }
530 {
531  def("get_idhdl", get_idhdl);
532  boost::python::class_<arg_list>("i_arg_list")
533  .def("append", &arg_list::appendPoly)
534  .def("append", &arg_list::appendArray)
535  .def("append", &arg_list::appendNumber)
536  .def("append", &arg_list::appendint)
537  .def("append", &arg_list::appendIdeal)
538  .def("append", &arg_list::appendModule)
539  .def("append", &arg_list::appendPrelist)
540  .def("append", &arg_list::appendVector)
541  .def("append", &arg_list::appendRing)
542  .def("append", &arg_list::appendIntvec)
543  .def("append", &arg_list::appendString);
544  boost::python::class_<idhdl_wrap>("interpreter_id")
545  .def("is_zero", &idhdl_wrap::is_zero)
546  .def("is_proc", &idhdl_wrap::id_is_proc)
547  .def("print_type", &idhdl_wrap::print_type)
548  .def("write", &idhdl_wrap::writePoly)
549  .def("write", &idhdl_wrap::writeArray)
550  .def("write", &idhdl_wrap::writeNumber)
551  .def("write", &idhdl_wrap::writeint)
552  .def("write", &idhdl_wrap::writeIdeal)
553  .def("write", &idhdl_wrap::writeModule)
554  .def("write", &idhdl_wrap::writeVector)
555  .def("write", &idhdl_wrap::writeList)
556  .def("write", &idhdl_wrap::writeString)
557  .def("write", &idhdl_wrap::writeIntvec)
558  .def("write", &idhdl_wrap::writeRing)
559  .def("__str__", idhdl_as_str);
560  def("call_interpreter_method",call_interpreter_method);
561  def("cbm",call_builtin_method_general);
562  def("transfer_to_python",buildPyObjectFromIdhdl);
563  def("is_builtin", is_builtin);
564 }
565 #endif
#define TRUE
Definition: auxiliary.h:100
void * ADDRESS
Definition: auxiliary.h:119
int l
Definition: cfEzgcd.cc:100
int m
Definition: cfEzgcd.cc:128
int i
Definition: cfEzgcd.cc:132
Variable x
Definition: cfModGcd.cc:4082
int p
Definition: cfModGcd.cc:4078
FILE * f
Definition: checklibs.c:9
unsigned char * proc[NUM_PROC]
Definition: checklibs.c:16
Definition: Ideal.h:88
Definition: IIntvec.h:6
intvec * allocate_legacy_intvec_copy() const
Definition: IIntvec.h:21
Definition: Ideal.h:121
Definition: Number.h:34
Definition: ring_wrap.h:21
intrusive_ptr< ip_sring > pimpl
Definition: ring_wrap.h:23
Variable next() const
Definition: factory.h:146
Definition: Poly.h:509
void appendint(int p)
void internal_append(leftv v)
void appendArray(const NumpyArrayType &f)
void appendPrelist(arg_list &l)
void appendNumber(const Number &p)
void appendVector(const Vector &p)
void appendString(const char *s)
void appendIntvec(Intvec &iv)
void appendModule(const Module &p)
void appendPoly(const Poly &p)
void appendIdeal(const Ideal &p)
void appendRing(const Ring &r)
void writeIdeal(const Ideal &p)
void writeList(arg_list &f)
void writePoly(const Poly &p)
void writeString(const char *s)
idhdl_wrap(idhdl id)
void writeNumber(const Number &p)
void writeIntvec(const Intvec &iv)
void writeVector(const Vector &p)
void writeArray(const NumpyArrayType &f)
void writeRing(const Ring &r)
void writeModule(const Module &p)
void writeint(int p)
Definition: idrec.h:35
utypes data
Definition: idrec.h:40
int typ
Definition: idrec.h:43
Definition: intvec.h:23
Class used for (list of) interpreter objects.
Definition: subexpr.h:83
leftv next
Definition: subexpr.h:86
void CleanUp(ring r=currRing)
Definition: subexpr.cc:348
Definition: lists.h:24
static FORCE_INLINE void n_Delete(number *p, const coeffs r)
delete 'p'
Definition: coeffs.h:455
#define Print
Definition: emacs.cc:80
const CanonicalForm int s
Definition: facAbsFact.cc:51
CanonicalForm res
Definition: facAbsFact.cc:60
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39
int j
Definition: facHensel.cc:110
char name(const Variable &v)
Definition: factory.h:189
VAR short errorreported
Definition: feFopen.cc:23
#define EXTERN_VAR
Definition: globaldefs.h:6
@ IDEAL_CMD
Definition: grammar.cc:284
@ MATRIX_CMD
Definition: grammar.cc:286
@ PROC_CMD
Definition: grammar.cc:280
@ MODUL_CMD
Definition: grammar.cc:287
@ VECTOR_CMD
Definition: grammar.cc:292
@ NUMBER_CMD
Definition: grammar.cc:288
@ POLY_CMD
Definition: grammar.cc:289
@ RING_CMD
Definition: grammar.cc:281
STATIC_VAR poly last
Definition: hdegree.cc:1151
bool is_builtin(const char *name)
static NumpyArrayType buildPythonMatrix(matrix m, ring r)
boost::python::object call_builtin_method_general(const char *name, arg_list &l)
matrix matrixFromArray(const NumpyArrayType &f)
void export_interpreter()
static boost::python::str idhdl_as_str(idhdl_wrap iw)
static idhdl_wrap get_idhdl(const char *n)
static void free_leftv(leftv args)
boost::python::list buildPythonList(lists l, ring r)
EXTERN_VAR int inerror
boost::python::object call_interpreter_method(const idhdl_wrap &proc, const arg_list &args)
boost::python::object buildPyObjectFromLeftv(leftv v)
boost::python::numeric::array NumpyArrayType
boost::python::object buildPyObjectFromIdhdl(const idhdl_wrap &id)
static BOOLEAN length(leftv result, leftv arg)
Definition: interval.cc:257
BOOLEAN iiExprArith2(leftv res, leftv a, int op, leftv b, BOOLEAN proccall)
Definition: iparith.cc:8881
int IsCmd(const char *n, int &tok)
Definition: iparith.cc:9480
BOOLEAN iiExprArith1(leftv res, leftv a, int op)
Definition: iparith.cc:9070
BOOLEAN iiExprArithM(leftv res, leftv a, int op)
Definition: iparith.cc:9371
BOOLEAN iiExprArith3(leftv res, int op, leftv a, leftv b, leftv c)
Definition: iparith.cc:9280
idhdl ggetid(const char *n)
Definition: ipid.cc:572
EXTERN_VAR omBin sleftv_bin
Definition: ipid.h:145
BOOLEAN iiMake_proc(idhdl pn, package pack, leftv args)
Definition: iplib.cc:504
INST_VAR sleftv iiRETURNEXPR
Definition: iplib.cc:474
VAR omBin slists_bin
Definition: lists.cc:23
matrix mpNew(int r, int c)
create a r x c zero-matrix
Definition: matpol.cc:37
#define MATELEM(mat, i, j)
1-based access to matrix
Definition: matpol.h:29
#define MATROWS(i)
Definition: matpol.h:26
#define MATCOLS(i)
Definition: matpol.h:27
#define assume(x)
Definition: mod2.h:387
slists * lists
Definition: mpr_numeric.h:146
char * str(leftv arg)
Definition: shared.cc:704
#define omStrDup(s)
Definition: omAllocDecl.h:263
#define omAllocBin(bin)
Definition: omAllocDecl.h:205
#define omAlloc0Bin(bin)
Definition: omAllocDecl.h:206
#define omFree(addr)
Definition: omAllocDecl.h:261
#define omFreeBin(addr, bin)
Definition: omAllocDecl.h:259
#define NULL
Definition: omList.c:12
static void p_Delete(poly *p, const ring r)
Definition: p_polys.h:901
VAR ring currRing
Widely used global variable which specifies the current polynomial ring for Singular interpreter and ...
Definition: polys.cc:13
idrec * idhdl
Definition: ring.h:21
void id_Delete(ideal *h, ring r)
deletes an ideal/module/matrix
Definition: janet.h:15
sleftv * leftv
Definition: structs.h:57
@ LIST_CMD
Definition: tok.h:118
@ INTVEC_CMD
Definition: tok.h:101
@ STRING_CMD
Definition: tok.h:185
@ INT_CMD
Definition: tok.h:96