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