1 /****************************************
2 *  Computer Algebra System SINGULAR     *
3 ****************************************/
4 /*
5 * ABSTRACT: automatic type conversions
6 */
7 
8 
9 
10 
11 #include "kernel/mod2.h"
12 #include "Singular/tok.h"
13 #include "Singular/ipid.h"
14 #include "misc/intvec.h"
15 #include "misc/options.h"
16 #include "kernel/polys.h"
17 #include "kernel/ideals.h"
18 #include "Singular/subexpr.h"
19 #include "coeffs/numbers.h"
20 #include "coeffs/coeffs.h"
21 #include "coeffs/bigintmat.h"
22 //#include "polys/ext_fields/longalg.h"
23 #include "polys/matpol.h"
24 #include "Singular/links/silink.h"
25 #include "kernel/GBEngine/syz.h"
26 #include "Singular/attrib.h"
27 #include "polys/monomials/ring.h"
28 #include "Singular/ipshell.h"
29 #include "Singular/number2.h"
30 #include "Singular/ipconv.h"
31 
32 typedef void *   (*iiConvertProc)(void * data);
33 typedef void    (*iiConvertProcL)(leftv out,leftv in);
34 struct sConvertTypes
35 {
36   int i_typ;
37   int o_typ;
38   iiConvertProc p;
39   iiConvertProcL pl;
40 };
41 
42 // all of these static conversion routines work destructive on their input
43 
iiI2P(void * data)44 static void * iiI2P(void *data)
45 {
46   poly p=pISet((int)(long)data);
47   return (void *)p;
48 }
49 
iiBI2P(void * data)50 static void * iiBI2P(void *data)
51 {
52   nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
53   if (nMap==NULL)
54   {
55     Werror("no conversion from bigint to %s", nCoeffName(currRing->cf));
56     return NULL;
57   }
58   number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
59   n_Delete((number *)&data, coeffs_BIGINT);
60   poly p=p_NSet(n, currRing);
61   return (void *)p;
62 }
63 
iiBu2P(leftv out,leftv in)64 static void iiBu2P(leftv out, leftv in)
65 {
66   sBucket_pt b=(sBucket_pt)in->CopyD();
67   poly p; int l;
68   sBucketDestroyAdd(b,&p,&l);
69   out->data=(void*)p;
70 }
71 
iiI2V(void * data)72 static void * iiI2V(void *data)
73 {
74   poly p=pISet((int)(long)data);
75   if (p!=NULL) pSetComp(p,1);
76   return (void *)p;
77 }
78 
iiBI2V(void * data)79 static void * iiBI2V(void *data)
80 {
81   nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
82   if (nMap==NULL)
83   {
84     Werror("no conversion from bigint to %s", nCoeffName(currRing->cf));
85     return NULL;
86   }
87   number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
88   n_Delete((number *)&data, coeffs_BIGINT);
89   poly p=p_NSet(n, currRing);
90   if (p!=NULL) pSetComp(p,1);
91   return (void *)p;
92 }
93 
iiI2Id(void * data)94 static void * iiI2Id(void *data)
95 {
96   ideal I=idInit(1,1);
97   I->m[0]=pISet((int)(long)data);
98   return (void *)I;
99 }
100 
iiBI2Id(void * data)101 static void * iiBI2Id(void *data)
102 {
103   ideal I=idInit(1,1);
104   nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
105   if (nMap==NULL)
106   {
107     Werror("no conversion from bigint to %s", nCoeffName(currRing->cf));
108     return NULL;
109   }
110   number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
111   n_Delete((number *)&data,coeffs_BIGINT);
112   poly p=pNSet(n);
113   I->m[0]=p;
114   return (void *)I;
115 }
iiBu2V(void * data)116 static void * iiBu2V(void *data)
117 {
118   poly p=NULL;
119   if (data!=NULL)
120   {
121     sBucket_pt b=(sBucket_pt)data;
122     int l;
123     sBucketDestroyAdd(b,&p,&l);
124     if (p!=NULL) pSetCompP(p,1);
125   }
126   return (void *)p;
127 }
128 
iiP2V(void * data)129 static void * iiP2V(void *data)
130 {
131   poly p=(poly)data;
132   if (p!=NULL) pSetCompP(p,1);
133   return (void *)p;
134 }
135 
iiBu2Id(void * data)136 static void * iiBu2Id(void *data)
137 {
138   ideal I=idInit(1,1);
139 
140   if (data!=NULL)
141   {
142     sBucket_pt b=(sBucket_pt)data;
143     poly p; int l;
144     sBucketDestroyAdd(b,&p,&l);
145     I->m[0]=p;
146   }
147   return (void *)I;
148 }
149 
iiP2Id(void * data)150 static void * iiP2Id(void *data)
151 {
152   ideal I=idInit(1,1);
153 
154   if (data!=NULL)
155   {
156     poly p=(poly)data;
157     I->m[0]=p;
158     if (pGetComp(p)!=0) I->rank=pMaxComp(p);
159   }
160   return (void *)I;
161 }
162 
iiV2Ma(void * data)163 static void * iiV2Ma(void *data)
164 {
165   matrix m=(matrix)idVec2Ideal((poly)data);
166   int h=MATCOLS(m);
167   MATCOLS(m)=MATROWS(m);
168   MATROWS(m)=h;
169   m->rank=h;
170   pDelete((poly *)&data);
171   return (void *)m;
172 }
173 
174 static void * iiN2P(void *data);
175 
iiDummy(void * data)176 static void * iiDummy(void *data)
177 {
178   return data;
179 }
180 
iiMo2Ma(void * data)181 static void * iiMo2Ma(void *data)
182 {
183   void *res=id_Module2Matrix((ideal)data,currRing);
184   return res;
185 }
186 
iiMa2Mo(void * data)187 static void * iiMa2Mo(void *data)
188 {
189   void *res=id_Matrix2Module((matrix)data,currRing);
190   return res;
191 }
192 
iiI2Iv(void * data)193 static void * iiI2Iv(void *data)
194 {
195   int s=(int)(long)data;
196   intvec *iv=new intvec(s,s);
197   return (void *)iv;
198 }
199 
iiI2N(void * data)200 static void * iiI2N(void *data)
201 {
202   number n=nInit((int)(long)data);
203   return (void *)n;
204 }
205 
iiI2BI(void * data)206 static void * iiI2BI(void *data)
207 {
208   number n=n_Init((int)(long)data, coeffs_BIGINT);
209   return (void *)n;
210 }
211 
212 #ifdef SINGULAR_4_2
iiI2NN(void * data)213 static void * iiI2NN(void *data)
214 {
215   if (currRing==NULL)
216   {
217     WerrorS("missing basering while converting int to Number");
218     return NULL;
219   }
220   number n=nInit((int)(long)data);
221   number2 nn=(number2)omAlloc(sizeof(*nn));
222   nn->cf=currRing->cf; nn->cf->ref++;
223   nn->n=n;
224   return (void *)nn;
225 }
iiI2CP(void * data)226 static void * iiI2CP(void *data)
227 {
228   if (currRing==NULL)
229   {
230     WerrorS("missing basering while converting int to Poly");
231     return NULL;
232   }
233   poly n=pISet((int)(long)data);
234   poly2 nn=(poly2)omAlloc(sizeof(*nn));
235   nn->cf=currRing; nn->cf->ref++;
236   nn->n=n;
237   return (void *)nn;
238 }
239 #endif
240 
iiBI2N(void * data)241 static void * iiBI2N(void *data)
242 {
243   if (currRing==NULL) return NULL;
244   nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
245   if (nMap==NULL)
246   {
247     Werror("no conversion from bigint to %s", nCoeffName(currRing->cf));
248     return NULL;
249   }
250   number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
251   n_Delete((number *)&data, coeffs_BIGINT);
252   return (void*)n;
253 }
254 
255 #ifdef SINGULAR_4_2
iiBI2NN(void * data)256 static void * iiBI2NN(void *data)
257 {
258   if (currRing==NULL)
259   {
260     WerrorS("missing basering while converting bigint to Number");
261     return NULL;
262   }
263   nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
264   if (nMap==NULL)
265   {
266     Werror("no conversion from bigint to %s",currRing->cf->cfCoeffName(currRing->cf));
267     return NULL;
268   }
269   number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
270   n_Delete((number *)&data, coeffs_BIGINT);
271   number2 nn=(number2)omAlloc(sizeof(*nn));
272   nn->cf=currRing->cf; nn->cf->ref++;
273   nn->n=n;
274   return (void*)nn;
275 }
iiBI2CP(void * data)276 static void * iiBI2CP(void *data)
277 {
278   if (currRing==NULL)
279   {
280     WerrorS("missing basering while converting bigint to Poly");
281     return NULL;
282   }
283   nMapFunc nMap=n_SetMap(coeffs_BIGINT,currRing->cf);
284   if (nMap==NULL)
285   {
286     Werror("no conversion from bigint to %s",currRing->cf->cfCoeffName(currRing->cf));
287     return NULL;
288   }
289   number n=nMap((number)data,coeffs_BIGINT,currRing->cf);
290   n_Delete((number *)&data, coeffs_BIGINT);
291   poly2 nn=(poly2)omAlloc(sizeof(*nn));
292   nn->cf=currRing; nn->cf->ref++;
293   nn->n=pNSet(n);
294   return (void*)nn;
295 }
iiP2CP(void * data)296 static void * iiP2CP(void *data)
297 {
298   poly2 nn=(poly2)omAlloc(sizeof(*nn));
299   nn->cf=currRing; nn->cf->ref++;
300   nn->n=(poly)data;
301   return (void*)nn;
302 }
303 #endif
304 
305 #ifdef SINGULAR_4_2
iiNN2N(void * data)306 static void * iiNN2N(void *data)
307 {
308   number2 d=(number2)data;
309   if ((currRing==NULL)
310   || (currRing->cf!=d->cf))
311   {
312     WerrorS("cannot convert: incompatible");
313     return NULL;
314   }
315   number n = n_Copy(d->n, d->cf);
316   n2Delete(d);
317   return (void*)n;
318 }
319 #endif
320 
321 #ifdef SINGULAR_4_2
iiNN2P(void * data)322 static void * iiNN2P(void *data)
323 {
324   number2 d=(number2)data;
325   if ((currRing==NULL)
326   || (currRing->cf!=d->cf))
327   {
328     WerrorS("cannot convert: incompatible");
329     return NULL;
330   }
331   number n = n_Copy(d->n, d->cf);
332   n2Delete(d);
333   return (void*)p_NSet(n,currRing);
334 }
335 #endif
336 
iiIm2Ma(void * data)337 static void * iiIm2Ma(void *data)
338 {
339   int i, j;
340   intvec *iv = (intvec *)data;
341   matrix m = mpNew(iv->rows(), iv->cols());
342 
343   for (i=iv->rows(); i>0; i--)
344   {
345     for (j=iv->cols(); j>0; j--)
346     {
347       MATELEM(m, i, j) = pISet(IMATELEM(*iv, i, j));
348     }
349   }
350   delete iv;
351   return (void *)m;
352 }
353 
iiIm2Bim(void * data)354 static void * iiIm2Bim(void *data)
355 {
356   intvec *iv=(intvec*)data;
357   void *r=(void *)iv2bim(iv,coeffs_BIGINT);
358   delete iv;
359   return r;
360 }
361 
iiN2P(void * data)362 static void * iiN2P(void *data)
363 {
364   poly p=NULL;
365   if (!nIsZero((number)data))
366   {
367     p=pNSet((number)data);
368   }
369   //else
370   //{
371   //  nDelete((number *)&data);
372   //}
373   return (void *)p;
374 }
375 
iiN2Ma(void * data)376 static void * iiN2Ma(void *data)
377 {
378   ideal I=idInit(1,1);
379   if (!nIsZero((number)data))
380   {
381     poly p=pNSet((number)data);
382     I->m[0]=p;
383   }
384   //else
385   //{
386   //  nDelete((number *)&data);
387   //}
388   return (void *)I;
389 }
390 
iiS2Link(void * data)391 static void * iiS2Link(void *data)
392 {
393   si_link l=(si_link)omAlloc0Bin(ip_link_bin);
394   slInit(l, (char *) data);
395   omFree((ADDRESS)data);
396   return (void *)l;
397 }
398 
iiR2L_l(leftv out,leftv in)399 static void iiR2L_l(leftv out, leftv in)
400 {
401   int add_row_shift = 0;
402   intvec *weights=(intvec*)atGet(in,"isHomog",INTVEC_CMD);
403   if (weights!=NULL)  add_row_shift=weights->min_in();
404 
405   syStrategy tmp=(syStrategy)in->CopyD();
406 
407   out->data=(void *)syConvRes(tmp,TRUE,add_row_shift);
408 }
409 
iiL2R(leftv out,leftv in)410 static void iiL2R(leftv out, leftv in)
411 {
412   //int add_row_shift = 0;
413   lists l=(lists)in->Data();
414   intvec *ww=NULL;
415   if (l->nr>=0) ww=(intvec *)atGet(&(l->m[0]),"isHomog",INTVEC_CMD);
416   out->data=(void *)syConvList(l);
417   if (ww!=NULL)
418   {
419     intvec *weights=ivCopy(ww);
420     atSet(out,omStrDup("isHomog"),weights,INTVEC_CMD);
421   }
422 }
423 
424 //
425 // automatic conversions:
426 //
427 #define IPCONV
428 #define D(A)     A
429 #define NULL_VAL NULL
430 #include "Singular/table.h"
431 /*2
432 * try to convert 'input' of type 'inputType' to 'output' of type 'outputType'
433 * return FALSE on success
434 */
iiConvert(int inputType,int outputType,int index,leftv input,leftv output,const struct sConvertTypes * dConvertTypes)435 BOOLEAN iiConvert (int inputType, int outputType, int index, leftv input, leftv output,const struct sConvertTypes *dConvertTypes)
436 {
437   output->Init();
438   if ((inputType==outputType)
439   || (outputType==DEF_CMD)
440   || ((outputType==IDHDL)&&(input->rtyp==IDHDL)))
441   {
442     memcpy(output,input,sizeof(*output));
443     input->Init();
444     return FALSE;
445   }
446   else if (outputType==ANY_TYPE)
447   {
448     output->rtyp=ANY_TYPE;
449     output->data=(char *)(long)input->Typ();
450     /* the name of the object:*/
451     if (input->e==NULL)
452     {
453       if (input->rtyp==IDHDL)
454       /* preserve name: copy it */
455         output->name=omStrDup(IDID((idhdl)(input->data)));
456       else if (input->name!=NULL)
457       {
458         if (input->rtyp==ALIAS_CMD)
459         output->name=omStrDup(input->name);
460         else
461         {
462           output->name=input->name;
463           input->name=NULL;
464         }
465       }
466       else if ((input->rtyp==POLY_CMD) && (input->name==NULL))
467       {
468         if (input->data!=NULL)
469         {
470           int nr=pIsPurePower((poly)input->data);
471           if (nr!=0)
472           {
473             if (pGetExp((poly)input->data,nr)==1)
474             {
475               output->name=omStrDup(currRing->names[nr-1]);
476             }
477             else
478             {
479               char *tmp=(char *)omAlloc(4);
480               sprintf(tmp,"%c%d",*(currRing->names[nr-1]),
481                 (int)pGetExp((poly)input->data,nr));
482               output->name=tmp;
483             }
484           }
485           else if(pIsConstant((poly)input->data))
486           {
487             StringSetS("");
488             number n=(pGetCoeff((poly)input->data));
489             n_Write(n, currRing->cf);
490             (pGetCoeff((poly)input->data))=n; // n_Write may have changed n
491             output->name=StringEndS();
492           }
493         }
494       }
495       else if ((input->rtyp==NUMBER_CMD) && (input->name==NULL))
496       {
497         StringSetS("");
498         number n=(number)input->data;
499         n_Write(n, currRing->cf);
500         input->data=(void*)n; // n_Write may have changed n
501         output->name=StringEndS();
502       }
503       else
504       {
505         /* no need to preserve name: use it */
506         output->name=input->name;
507         input->name=NULL;
508       }
509     }
510     output->next=input->next;
511     input->next=NULL;
512     if (!errorreported) input->CleanUp();
513     return errorreported;
514   }
515   if (index!=0) /* iiTestConvert does not returned 'failure' */
516   {
517     index--;
518 
519     if((dConvertTypes[index].i_typ==inputType)
520     &&(dConvertTypes[index].o_typ==outputType))
521     {
522       if(traceit&TRACE_CONV)
523       {
524         Print("automatic  conversion %s -> %s\n",
525         Tok2Cmdname(inputType),Tok2Cmdname(outputType));
526       }
527       if ((currRing==NULL) && (outputType>BEGIN_RING) && (outputType<END_RING))
528         return TRUE;
529       output->rtyp=outputType;
530       if (dConvertTypes[index].p!=NULL)
531       {
532         output->data=dConvertTypes[index].p(input->CopyD());
533       }
534       else
535       {
536         dConvertTypes[index].pl(output,input);
537       }
538       if ((output->data==NULL)
539       && ((outputType!=INT_CMD)
540         &&(outputType!=POLY_CMD)
541         &&(outputType!=VECTOR_CMD)
542         &&(outputType!=NUMBER_CMD)))
543       {
544         return TRUE;
545       }
546       if (errorreported) return TRUE;
547       output->next=input->next;
548       input->next=NULL;
549       if ((input->rtyp!=IDHDL) && (input->attribute!=NULL))
550       {
551         input->attribute->killAll(currRing);
552         input->attribute=NULL;
553       }
554       if (input->e!=NULL)
555       {
556         Subexpr h;
557         while (input->e!=NULL)
558         {
559           h=input->e->next;
560           omFreeBin((ADDRESS)input->e, sSubexpr_bin);
561           input->e=h;
562         }
563       }
564       //input->Init(); // seems that input (rtyp?) is still needed
565       return FALSE;
566     }
567   }
568   return TRUE;
569 }
570 
571 /*2
572 * try to convert 'inputType' in 'outputType'
573 * return 0 on failure, an index (<>0) on success
574 */
iiTestConvert(int inputType,int outputType,const struct sConvertTypes * dConvertTypes)575 int iiTestConvert (int inputType, int outputType,const struct sConvertTypes *dConvertTypes)
576 {
577   if ((inputType==outputType)
578   || (outputType==DEF_CMD)
579   || (outputType==IDHDL)
580   || (outputType==ANY_TYPE))
581   {
582     return -1;
583   }
584   if (inputType==UNKNOWN) return 0;
585 
586   if ((currRing==NULL) && (outputType>BEGIN_RING) && (outputType<END_RING))
587     return 0;
588   //if ((currRing==NULL) && (outputType==CNUMBER_CMD))
589   //  return 0;
590 
591   // search the list
592   int i=0;
593   while (dConvertTypes[i].i_typ!=0)
594   {
595     if((dConvertTypes[i].i_typ==inputType)
596     &&(dConvertTypes[i].o_typ==outputType))
597     {
598       //Print("test convert %d to %d (%s -> %s):%d\n",inputType,outputType,
599       //Tok2Cmdname(inputType), Tok2Cmdname(outputType),i+1);
600       return i+1;
601     }
602     i++;
603   }
604   //Print("test convert %d to %d (%s -> %s):0, tested:%d\n",inputType,outputType,
605   // Tok2Cmdname(inputType), Tok2Cmdname(outputType),i);
606   return 0;
607 }
608