My Project  debian-1:4.1.1-p2+ds-4
interpreter_support.cc
Go to the documentation of this file.
1 #include "kernel/mod2.h"
2 #ifdef HAVE_PYTHON_MOD
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"
21 extern int inerror;
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 
37 matrix matrixFromArray(const NumpyArrayType& f)
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:
65  leftv args;
66  arg_list()
67  {
68  args=(leftv) NULL;
69  }
70  ~arg_list()
71  {
72  if (args!=NULL)
73  {
74  args->CleanUp();
75  omFreeBin(args, sleftv_bin);
76  }
77  }
78  leftv pop_front()
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  }
139  void appendArray(const NumpyArrayType& f)
140  {
141  leftv v=initArg();
142  matrix m=matrixFromArray(f);
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  }
162  lists dumpToLists()
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  }
177  void appendPrelist(arg_list& l)
178  {
179  leftv v=initArg();
180  v->data=l.dumpToLists();
181  v->rtyp=LIST_CMD;
182  internal_append(v);
183  }
184  void appendIntvec(Intvec& iv)
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:
192  leftv initArg()
193  {
195  res->Init();
196  return res;
197  }
198  void internal_append(leftv v)
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 
214 class idhdl_wrap
215 {
216  public:
217  idhdl id;
218  idhdl_wrap(idhdl id)
219  {
220  this->id=id;
221  }
222  idhdl_wrap()
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  }
285  void writeArray(const NumpyArrayType& f)
286  {
287  if(id->typ=MATRIX_CMD)
288  {
289  matrix m=matrixFromArray(f);
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  }
320  void writeList(arg_list& f)
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 
332 static NumpyArrayType buildPythonMatrix(matrix m, ring r)
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 
461  return buildPyObjectFromLeftv(&iiRETURNEXPR);
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 }
514 static boost::python::str idhdl_as_str(idhdl_wrap iw)
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 }
529 void export_interpreter()
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
Ring
Definition: ring_wrap.h:20
idrec::data
utypes data
Definition: idrec.h:39
ip_smatrix
Definition: matpol.h:13
j
int j
Definition: facHensel.cc:105
f
FILE * f
Definition: checklibs.c:9
omFree
#define omFree(addr)
Definition: omAllocDecl.h:259
Poly
Definition: janet.h:14
errorreported
short errorreported
Definition: feFopen.cc:23
Intvec
Definition: IIntvec.h:5
ring_wrap.h
x
Variable x
Definition: cfModGcd.cc:4023
NUMBER_CMD
Definition: grammar.cc:287
MATELEM
#define MATELEM(mat, i, j)
Definition: matpol.h:28
iiExprArith1
BOOLEAN iiExprArith1(leftv res, leftv a, int op)
Definition: iparith.cc:8267
iiMake_proc
BOOLEAN iiMake_proc(idhdl pn, package pack, leftv sl)
Definition: iplib.cc:484
LIST_CMD
Definition: tok.h:117
lists.h
inerror
int inerror
Definition: grammar.cc:175
ADDRESS
void * ADDRESS
Definition: auxiliary.h:133
MODUL_CMD
Definition: grammar.cc:286
STRING_CMD
Definition: tok.h:182
Intvec::allocate_legacy_intvec_copy
intvec * allocate_legacy_intvec_copy() const
Definition: IIntvec.h:21
iiExprArithM
BOOLEAN iiExprArithM(leftv res, leftv a, int op)
Definition: iparith.cc:8570
length
static BOOLEAN length(leftv result, leftv arg)
Definition: interval.cc:267
omStrDup
#define omStrDup(s)
Definition: omAllocDecl.h:261
n_Delete
static FORCE_INLINE void n_Delete(number *p, const coeffs r)
delete 'p'
Definition: coeffs.h:455
intvec_wrap.h
omAllocBin
#define omAllocBin(bin)
Definition: omAllocDecl.h:203
omAlloc0Bin
#define omAlloc0Bin(bin)
Definition: omAllocDecl.h:204
Variable::next
Variable next() const
Definition: factory.h:137
sleftv
Class used for (list of) interpreter objects.
Definition: subexpr.h:81
idhdl
idrec * idhdl
Definition: ring.h:20
RING_CMD
Definition: grammar.cc:281
slists_bin
omBin slists_bin
Definition: lists.cc:22
MATRIX_CMD
Definition: grammar.cc:285
leftv
sleftv * leftv
Definition: structs.h:59
currRing
ring currRing
Widely used global variable which specifies the current polynomial ring for Singular interpreter and ...
Definition: polys.cc:13
TRUE
#define TRUE
Definition: auxiliary.h:98
i
int i
Definition: cfEzgcd.cc:125
id_Delete
void id_Delete(ideal *h, ring r)
deletes an ideal/module/matrix
Definition: simpleideals.cc:113
res
CanonicalForm res
Definition: facAbsFact.cc:64
INT_CMD
Definition: tok.h:95
matpol.h
PROC_CMD
Definition: grammar.cc:280
structs.h
Ideal.h
Number
Definition: Number.h:33
IDEAL_CMD
Definition: grammar.cc:283
mod2.h
intvec
Definition: intvec.h:16
Module
Definition: Ideal.h:119
VECTOR_CMD
Definition: grammar.cc:290
subexpr.h
iiExprArith3
BOOLEAN iiExprArith3(leftv res, int op, leftv a, leftv b, leftv c)
Definition: iparith.cc:8480
sleftv::CleanUp
void CleanUp(ring r=currRing)
Definition: subexpr.cc:327
mpNew
matrix mpNew(int r, int c)
create a r x c zero-matrix
Definition: matpol.cc:35
last
static poly last
Definition: hdegree.cc:1077
slists
Definition: lists.h:21
poly_wrap.h
INTVEC_CMD
Definition: tok.h:100
idrec
Definition: idrec.h:33
export_interpreter
void export_interpreter()
p_Delete
static void p_Delete(poly *p, const ring r)
Definition: p_polys.h:842
IsCmd
int IsCmd(const char *n, int &tok)
Definition: iparith.cc:8679
Ring::pimpl
intrusive_ptr< ip_sring > pimpl
Definition: ring_wrap.h:23
iiExprArith2
BOOLEAN iiExprArith2(leftv res, leftv a, int op, leftv b, BOOLEAN proccall)
Definition: iparith.cc:8078
Print
#define Print
Definition: emacs.cc:79
Poly.h
iiRETURNEXPR
sleftv iiRETURNEXPR
Definition: iplib.cc:454
name
char name(const Variable &v)
Definition: factory.h:180
Ideal
Definition: Ideal.h:86
m
int m
Definition: cfEzgcd.cc:121
idrec::typ
int typ
Definition: idrec.h:42
MATCOLS
#define MATCOLS(i)
Definition: matpol.h:27
assume
#define assume(x)
Definition: mod2.h:384
NULL
#define NULL
Definition: omList.c:9
lists
slists * lists
Definition: mpr_numeric.h:145
l
int l
Definition: cfEzgcd.cc:93
v
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:37
sleftv_bin
omBin sleftv_bin
Definition: subexpr.cc:45
p
int p
Definition: cfModGcd.cc:4019
ggetid
idhdl ggetid(const char *n)
Definition: ipid.cc:512
s
const CanonicalForm int s
Definition: facAbsFact.cc:55
POLY_CMD
Definition: grammar.cc:288
ipshell.h
Vector
Definition: Poly.h:509
MATROWS
#define MATROWS(i)
Definition: matpol.h:26
proc
unsigned char * proc[NUM_PROC]
Definition: checklibs.c:16
omFreeBin
#define omFreeBin(addr, bin)
Definition: omAllocDecl.h:257
numbers.h
ipid.h
sleftv::next
leftv next
Definition: subexpr.h:85