source: git/Singular/iparith.cc @ 661c214

spielwiese
Last change on this file since 661c214 was 661c214, checked in by Frank Seelisch <seelisch@…>, 13 years ago
further separation of alg/transc ext code git-svn-id: file:///usr/local/Singular/svn/trunk@13903 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 202.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5
6/*
7* ABSTRACT: table driven kernel interface, used by interpreter
8*/
9
10#include <stdlib.h>
11#include <string.h>
12#include <ctype.h>
13#include <stdio.h>
14#include <time.h>
15#include <unistd.h>
16
17#include <kernel/mod2.h>
18#include <Singular/tok.h>
19#include <kernel/options.h>
20#include <Singular/ipid.h>
21#include <kernel/intvec.h>
22#include <omalloc/omalloc.h>
23#include <kernel/polys.h>
24#include <kernel/febase.h>
25#include <Singular/sdb.h>
26#include <kernel/longalg.h>
27#include <kernel/longtrans.h>
28#include <kernel/ideals.h>
29#include <kernel/matpol.h>
30#include <kernel/kstd1.h>
31#include <kernel/timer.h>
32#include <kernel/ring.h>
33#include <Singular/subexpr.h>
34#include <Singular/lists.h>
35#include <kernel/modulop.h>
36#ifdef HAVE_RINGS
37#include <kernel/rmodulon.h>
38#include <kernel/rmodulo2m.h>
39#include <kernel/rintegers.h>
40#endif
41#include <kernel/numbers.h>
42#include <kernel/stairc.h>
43#include <kernel/maps.h>
44#include <Singular/maps_ip.h>
45#include <kernel/syz.h>
46#include <kernel/weight.h>
47#include <Singular/ipconv.h>
48#include <Singular/ipprint.h>
49#include <Singular/attrib.h>
50#include <Singular/silink.h>
51#include <kernel/sparsmat.h>
52#include <kernel/units.h>
53#include <Singular/janet.h>
54#include <kernel/GMPrat.h>
55#include <kernel/tgb.h>
56#include <kernel/walkProc.h>
57#include <kernel/mod_raw.h>
58#include <Singular/MinorInterface.h>
59#include <kernel/linearAlgebra.h>
60#include <Singular/misc_ip.h>
61#ifdef HAVE_FACTORY
62#  include <kernel/clapsing.h>
63#  include <kernel/kstdfac.h>
64#endif /* HAVE_FACTORY */
65#ifdef HAVE_FACTORY
66#  include <kernel/fglm.h>
67#endif /* HAVE_FACTORY */
68#include <Singular/interpolation.h>
69
70#include <Singular/blackbox.h>
71#include <Singular/newstruct.h>
72#include <Singular/ipshell.h>
73#include <kernel/mpr_inout.h>
74
75#include <kernel/timer.h>
76
77#ifdef HAVE_PLURAL
78  #include <kernel/gring.h>
79  #include <kernel/sca.h>
80  #define ALLOW_PLURAL     1
81  #define NO_PLURAL        0
82  #define COMM_PLURAL      2
83  #define  PLURAL_MASK 3
84#else /* HAVE_PLURAL */
85  #define ALLOW_PLURAL     0
86  #define NO_PLURAL        0
87  #define COMM_PLURAL      0
88  #define  PLURAL_MASK     0
89#endif /* HAVE_PLURAL */
90
91#ifdef HAVE_RINGS
92  #define RING_MASK        4
93#else
94  #define RING_MASK        0
95#endif
96#define ALLOW_RING       4
97#define NO_RING          0
98
99/*=============== types =====================*/
100struct sValCmdTab
101{
102  short cmd;
103  short start;
104};
105
106typedef sValCmdTab jjValCmdTab[];
107
108struct _scmdnames
109{
110  char *name;
111  short alias;
112  short tokval;
113  short toktype;
114};
115typedef struct _scmdnames cmdnames;
116
117
118typedef char * (*Proc1)(char *);
119struct sValCmd1
120{
121  proc1 p;
122  short cmd;
123  short res;
124  short arg;
125  short valid_for;
126};
127
128typedef BOOLEAN (*proc2)(leftv,leftv,leftv);
129struct sValCmd2
130{
131  proc2 p;
132  short cmd;
133  short res;
134  short arg1;
135  short arg2;
136  short valid_for;
137};
138
139typedef BOOLEAN (*proc3)(leftv,leftv,leftv,leftv);
140struct sValCmd3
141{
142  proc3 p;
143  short cmd;
144  short res;
145  short arg1;
146  short arg2;
147  short arg3;
148  short valid_for;
149};
150struct sValCmdM
151{
152  proc1 p;
153  short cmd;
154  short res;
155  short number_of_args; /* -1: any, -2: any >0, .. */
156  short valid_for;
157};
158
159typedef struct
160{
161  cmdnames *sCmds;             /**< array of existing commands */
162  struct sValCmd1 *psValCmd1;
163  struct sValCmd2 *psValCmd2;
164  struct sValCmd3 *psValCmd3;
165  struct sValCmdM *psValCmdM;
166  int nCmdUsed;      /**< number of commands used */
167  int nCmdAllocated; /**< number of commands-slots allocated */
168  int nLastIdentifier; /**< valid indentifieres are slot 1..nLastIdentifier */
169} SArithBase;
170
171/*---------------------------------------------------------------------*
172 * File scope Variables (Variables share by several functions in
173 *                       the same file )
174 *
175 *---------------------------------------------------------------------*/
176static SArithBase sArithBase;  /**< Base entry for arithmetic */
177
178/*---------------------------------------------------------------------*
179 * Extern Functions declarations
180 *
181 *---------------------------------------------------------------------*/
182static int _gentable_sort_cmds(const void *a, const void *b);
183extern int iiArithRemoveCmd(char *szName);
184extern int iiArithAddCmd(const char *szName, short nAlias, short nTokval,
185                         short nToktype, short nPos=-1);
186
187/*============= proc =======================*/
188static BOOLEAN jjLOAD(leftv res, leftv v, BOOLEAN autoexport = FALSE);
189static int iiTabIndex(const jjValCmdTab dArithTab, const int len, const int op);
190#ifdef MDEBUG
191#define jjMakeSub(A) jjDBMakeSub(A,__FILE__,__LINE__)
192static Subexpr jjDBMakeSub(leftv e,const char *f,const  int l);
193#else
194static Subexpr jjMakeSub(leftv e);
195#endif
196
197/*============= vars ======================*/
198extern int cmdtok;
199extern BOOLEAN expected_parms;
200
201#define ii_div_by_0 "div. by 0"
202#define ii_not_for_plural "not implemented for non-commutative rings"
203#define ii_not_for_ring "not implemented for rings with rings as coeffients"
204
205int iiOp; /* the current operation*/
206
207/*=================== operations with 2 args.: static proc =================*/
208/* must be ordered: first operations for chars (infix ops),
209 * then alphabetically */
210
211static BOOLEAN jjOP_IV_I(leftv res, leftv u, leftv v)
212{
213  intvec* aa= (intvec *)u->CopyD(INTVEC_CMD);
214  int bb = (int)(long)(v->Data());
215  if (errorreported) return TRUE;
216  switch (iiOp)
217  {
218    case '+': (*aa) += bb; break;
219    case '-': (*aa) -= bb; break;
220    case '*': (*aa) *= bb; break;
221    case '/':
222    case INTDIV_CMD: (*aa) /= bb; break;
223    case '%':
224    case INTMOD_CMD: (*aa) %= bb; break;
225  }
226  res->data=(char *)aa;
227  return FALSE;
228}
229static BOOLEAN jjOP_I_IV(leftv res, leftv u, leftv v)
230{
231  return jjOP_IV_I(res,v,u);
232}
233static BOOLEAN jjOP_IM_I(leftv res, leftv u, leftv v)
234{
235  intvec* aa= (intvec *)u->CopyD(INTVEC_CMD);
236  int bb = (int)(long)(v->Data());
237  int i=si_min(aa->rows(),aa->cols());
238  switch (iiOp)
239  {
240    case '+': for (;i>0;i--) IMATELEM(*aa,i,i) += bb;
241              break;
242    case '-': for (;i>0;i--) IMATELEM(*aa,i,i) -= bb;
243              break;
244  }
245  res->data=(char *)aa;
246  return FALSE;
247}
248static BOOLEAN jjOP_I_IM(leftv res, leftv u, leftv v)
249{
250  return jjOP_IM_I(res,v,u);
251}
252static BOOLEAN jjCOLON(leftv res, leftv u, leftv v)
253{
254  int l=(int)(long)v->Data();
255  if (l>0)
256  {
257    int d=(int)(long)u->Data();
258    intvec *vv=new intvec(l);
259    int i;
260    for(i=l-1;i>=0;i--) { (*vv)[i]=d; }
261    res->data=(char *)vv;
262  }
263  return (l<=0);
264}
265static BOOLEAN jjDOTDOT(leftv res, leftv u, leftv v)
266{
267  res->data=(char *)new intvec((int)(long)u->Data(),(int)(long)v->Data());
268  return FALSE;
269}
270static void jjEQUAL_REST(leftv res,leftv u,leftv v);
271static BOOLEAN jjCOMPARE_IV(leftv res, leftv u, leftv v)
272{
273  intvec*    a = (intvec * )(u->Data());
274  intvec*    b = (intvec * )(v->Data());
275  int r=a->compare(b);
276  switch  (iiOp)
277  {
278    case '<':
279      res->data  = (char *) (r<0);
280      break;
281    case '>':
282      res->data  = (char *) (r>0);
283      break;
284    case LE:
285      res->data  = (char *) (r<=0);
286      break;
287    case GE:
288      res->data  = (char *) (r>=0);
289      break;
290    case EQUAL_EQUAL:
291    case NOTEQUAL: /* negation handled by jjEQUAL_REST */
292      res->data  = (char *) (r==0);
293      break;
294  }
295  jjEQUAL_REST(res,u,v);
296  if(r==-2) { WerrorS("size incompatible"); return TRUE; }
297  return FALSE;
298}
299static BOOLEAN jjCOMPARE_IV_I(leftv res, leftv u, leftv v)
300{
301  intvec* a = (intvec * )(u->Data());
302  int     b = (int)(long)(v->Data());
303  int r=a->compare(b);
304  switch  (iiOp)
305  {
306    case '<':
307      res->data  = (char *) (r<0);
308      break;
309    case '>':
310      res->data  = (char *) (r>0);
311      break;
312    case LE:
313      res->data  = (char *) (r<=0);
314      break;
315    case GE:
316      res->data  = (char *) (r>=0);
317      break;
318    case EQUAL_EQUAL:
319    case NOTEQUAL: /* negation handled by jjEQUAL_REST */
320      res->data  = (char *) (r==0);
321      break;
322  }
323  jjEQUAL_REST(res,u,v);
324  return FALSE;
325}
326static BOOLEAN jjCOMPARE_P(leftv res, leftv u, leftv v)
327{
328  poly p=(poly)u->Data();
329  poly q=(poly)v->Data();
330  int r=pCmp(p,q);
331  if (r==0)
332  {
333    number h=nSub(pGetCoeff(p),pGetCoeff(q));
334    /* compare lead coeffs */
335    r = -1+nIsZero(h)+2*nGreaterZero(h); /* -1: <, 0:==, 1: > */
336    nDelete(&h);
337  }
338  else if (p==NULL)
339  {
340    if (q==NULL)
341    {
342      /* compare 0, 0 */
343      r=0;
344    }
345    else if(pIsConstant(q))
346    {
347      /* compare 0, const */
348      r = 1-2*nGreaterZero(pGetCoeff(q)); /* -1: <, 1: > */
349    }
350  }
351  else if (q==NULL)
352  {
353    if (pIsConstant(p))
354    {
355      /* compare const, 0 */
356      r = -1+2*nGreaterZero(pGetCoeff(p)); /* -1: <, 1: > */
357    }
358  }
359  switch  (iiOp)
360  {
361    case '<':
362      res->data  = (char *) (r < 0);
363      break;
364    case '>':
365      res->data  = (char *) (r > 0);
366      break;
367    case LE:
368      res->data  = (char *) (r <= 0);
369      break;
370    case GE:
371      res->data  = (char *) (r >= 0);
372      break;
373    //case EQUAL_EQUAL:
374    //case NOTEQUAL: /* negation handled by jjEQUAL_REST */
375    //  res->data  = (char *) (r == 0);
376    //  break;
377  }
378  jjEQUAL_REST(res,u,v);
379  return FALSE;
380}
381static BOOLEAN jjCOMPARE_S(leftv res, leftv u, leftv v)
382{
383  char*    a = (char * )(u->Data());
384  char*    b = (char * )(v->Data());
385  int result = strcmp(a,b);
386  switch  (iiOp)
387  {
388    case '<':
389      res->data  = (char *) (result  < 0);
390      break;
391    case '>':
392      res->data  = (char *) (result  > 0);
393      break;
394    case LE:
395      res->data  = (char *) (result  <= 0);
396      break;
397    case GE:
398      res->data  = (char *) (result  >= 0);
399      break;
400    case EQUAL_EQUAL:
401    case NOTEQUAL: /* negation handled by jjEQUAL_REST */
402      res->data  = (char *) (result  == 0);
403      break;
404  }
405  jjEQUAL_REST(res,u,v);
406  return FALSE;
407}
408static BOOLEAN jjOP_REST(leftv res, leftv u, leftv v)
409{
410  if (u->Next()!=NULL)
411  {
412    u=u->next;
413    res->next = (leftv)omAllocBin(sleftv_bin);
414    return iiExprArith2(res->next,u,iiOp,v);
415  }
416  else if (v->Next()!=NULL)
417  {
418    v=v->next;
419    res->next = (leftv)omAllocBin(sleftv_bin);
420    return iiExprArith2(res->next,u,iiOp,v);
421  }
422  return FALSE;
423}
424static BOOLEAN jjPOWER_I(leftv res, leftv u, leftv v)
425{
426  int b=(int)(long)u->Data();
427  int e=(int)(long)v->Data();
428  int rc = 1;
429  BOOLEAN overflow=FALSE;
430  if (e >= 0)
431  {
432    if (b==0)
433    {
434      rc=(e==0);
435    }
436    else
437    {
438      int oldrc;
439      while ((e--)!=0)
440      {
441        oldrc=rc;
442        rc *= b;
443        if (!overflow)
444        {
445          if(rc/b!=oldrc) overflow=TRUE;
446        }
447      }
448      if (overflow)
449        WarnS("int overflow(^), result may be wrong");
450    }
451    res->data = (char *)((long)rc);
452    if (u!=NULL) return jjOP_REST(res,u,v);
453    return FALSE;
454  }
455  else
456  {
457    WerrorS("exponent must be non-negative");
458    return TRUE;
459  }
460}
461static BOOLEAN jjPOWER_BI(leftv res, leftv u, leftv v)
462{
463  int e=(int)(long)v->Data();
464  number n=(number)u->Data();
465  if (e>=0)
466  {
467    nlPower(n,e,(number*)&res->data);
468  }
469  else
470  {
471    WerrorS("exponent must be non-negative");
472    return TRUE;
473  }
474  if (u!=NULL) return jjOP_REST(res,u,v);
475  return FALSE;
476}
477static BOOLEAN jjPOWER_N(leftv res, leftv u, leftv v)
478{
479  int e=(int)(long)v->Data();
480  number n=(number)u->Data();
481  int d=0;
482  if (e<0)
483  {
484    n=nInvers(n);
485    e=-e;
486    d=1;
487  }
488  nPower(n,e,(number*)&res->data);
489  if (d) nDelete(&n);
490  if (u!=NULL) return jjOP_REST(res,u,v);
491  return FALSE;
492}
493static BOOLEAN jjPOWER_P(leftv res, leftv u, leftv v)
494{
495  int v_i=(int)(long)v->Data();
496  if (v_i<0)
497  {
498    WerrorS("exponent must be non-negative");
499    return TRUE;
500  }
501  poly u_p=(poly)u->CopyD(POLY_CMD);
502  int dummy;
503  if ((u_p!=NULL)
504  && (pTotaldegree(u_p)*(signed long)v_i > (signed long)currRing->bitmask))
505  {
506    Werror("OVERFLOW in power(d=%ld, e=%d, max=%ld)",
507                                    pTotaldegree(u_p),v_i,currRing->bitmask);
508    pDelete(&u_p);
509    return TRUE;
510  }
511  res->data = (char *)pPower(u_p,v_i);
512  if (u!=NULL) return jjOP_REST(res,u,v);
513  return errorreported; /* pPower may set errorreported via Werror */
514}
515static BOOLEAN jjPOWER_ID(leftv res, leftv u, leftv v)
516{
517  res->data = (char *)idPower((ideal)(u->Data()),(int)(long)(v->Data()));
518  if (u!=NULL) return jjOP_REST(res,u,v);
519  return FALSE;
520}
521static BOOLEAN jjPLUSMINUS_Gen(leftv res, leftv u, leftv v)
522{
523  u=u->next;
524  v=v->next;
525  if (u==NULL)
526  {
527    if (v==NULL) return FALSE;      /* u==NULL, v==NULL */
528    if (iiOp=='-')                  /* u==NULL, v<>NULL, iiOp=='-'*/
529    {
530      do
531      {
532        if (res->next==NULL)
533          res->next = (leftv)omAlloc0Bin(sleftv_bin);
534        leftv tmp_v=v->next;
535        v->next=NULL;
536        BOOLEAN b=iiExprArith1(res->next,v,'-');
537        v->next=tmp_v;
538        if (b)
539          return TRUE;
540        v=tmp_v;
541        res=res->next;
542      } while (v!=NULL);
543      return FALSE;
544    }
545    loop                            /* u==NULL, v<>NULL, iiOp=='+' */
546    {
547      res->next = (leftv)omAlloc0Bin(sleftv_bin);
548      res=res->next;
549      res->data = v->CopyD();
550      res->rtyp = v->Typ();
551      v=v->next;
552      if (v==NULL) return FALSE;
553    }
554  }
555  if (v!=NULL)                     /* u<>NULL, v<>NULL */
556  {
557    do
558    {
559      res->next = (leftv)omAlloc0Bin(sleftv_bin);
560      leftv tmp_u=u->next; u->next=NULL;
561      leftv tmp_v=v->next; v->next=NULL;
562      BOOLEAN b=iiExprArith2(res->next,u,iiOp,v);
563      u->next=tmp_u;
564      v->next=tmp_v;
565      if (b)
566        return TRUE;
567      u=tmp_u;
568      v=tmp_v;
569      res=res->next;
570    } while ((u!=NULL) && (v!=NULL));
571    return FALSE;
572  }
573  loop                             /* u<>NULL, v==NULL */
574  {
575    res->next = (leftv)omAlloc0Bin(sleftv_bin);
576    res=res->next;
577    res->data = u->CopyD();
578    res->rtyp = u->Typ();
579    u=u->next;
580    if (u==NULL) return FALSE;
581  }
582}
583static BOOLEAN jjCOLCOL(leftv res, leftv u, leftv v)
584{
585  idhdl packhdl;
586  switch(u->Typ())
587  {
588      case 0:
589        Print("%s of type 'ANY'. Trying load.\n", v->name);
590        if(iiTryLoadLib(u, u->name))
591        {
592          Werror("'%s' no such package", u->name);
593          return TRUE;
594        }
595        syMake(u,u->name,NULL);
596        // else: use next case !!! no break !!!
597      case PACKAGE_CMD:
598        packhdl = (idhdl)u->data;
599        if((!IDPACKAGE(packhdl)->loaded)
600        && (IDPACKAGE(packhdl)->language > LANG_TOP))
601        {
602          Werror("'%s' not loaded", u->name);
603          return TRUE;
604        }
605        if(v->rtyp == IDHDL)
606        {
607          v->name = omStrDup(v->name);
608        }
609        v->req_packhdl=IDPACKAGE(packhdl);
610        syMake(v, v->name, packhdl);
611        memcpy(res, v, sizeof(sleftv));
612        memset(v, 0, sizeof(sleftv));
613        break;
614      case DEF_CMD:
615        break;
616      default:
617        WerrorS("<package>::<id> expected");
618        return TRUE;
619  }
620  return FALSE;
621}
622static BOOLEAN jjPLUS_I(leftv res, leftv u, leftv v)
623{
624  unsigned int a=(unsigned int)(unsigned long)u->Data();
625  unsigned int b=(unsigned int)(unsigned long)v->Data();
626  unsigned int c=a+b;
627  res->data = (char *)((long)c);
628  if (((Sy_bit(31)&a)==(Sy_bit(31)&b))&&((Sy_bit(31)&a)!=(Sy_bit(31)&c)))
629  {
630    WarnS("int overflow(+), result may be wrong");
631  }
632  return jjPLUSMINUS_Gen(res,u,v);
633}
634static BOOLEAN jjPLUS_BI(leftv res, leftv u, leftv v)
635{
636  res->data = (char *)(nlAdd((number)u->Data(), (number)v->Data()));
637  return jjPLUSMINUS_Gen(res,u,v);
638}
639static BOOLEAN jjPLUS_N(leftv res, leftv u, leftv v)
640{
641  res->data = (char *)(nAdd((number)u->Data(), (number)v->Data()));
642  return jjPLUSMINUS_Gen(res,u,v);
643}
644static BOOLEAN jjPLUS_P(leftv res, leftv u, leftv v)
645{
646  res->data = (char *)(pAdd((poly)u->CopyD(POLY_CMD) , (poly)v->CopyD(POLY_CMD)));
647  return jjPLUSMINUS_Gen(res,u,v);
648}
649static BOOLEAN jjPLUS_IV(leftv res, leftv u, leftv v)
650{
651  res->data = (char *)ivAdd((intvec*)(u->Data()), (intvec*)(v->Data()));
652  if (res->data==NULL)
653  {
654     WerrorS("intmat size not compatible");
655     return TRUE;
656  }
657  return jjPLUSMINUS_Gen(res,u,v);
658  return FALSE;
659}
660static BOOLEAN jjPLUS_MA(leftv res, leftv u, leftv v)
661{
662  matrix A=(matrix)u->Data(); matrix B=(matrix)v->Data();
663  res->data = (char *)(mpAdd(A , B));
664  if (res->data==NULL)
665  {
666     Werror("matrix size not compatible(%dx%d, %dx%d)",
667             MATROWS(A),MATCOLS(A),MATROWS(B),MATCOLS(B));
668     return TRUE;
669  }
670  return jjPLUSMINUS_Gen(res,u,v);
671}
672static BOOLEAN jjPLUS_MA_P(leftv res, leftv u, leftv v)
673{
674  matrix m=(matrix)u->Data();
675  matrix p= mpInitP(m->nrows,m->ncols,(poly)(v->CopyD(POLY_CMD)));
676  if (iiOp=='+')
677    res->data = (char *)mpAdd(m , p);
678  else
679    res->data = (char *)mpSub(m , p);
680  idDelete((ideal *)&p);
681  return jjPLUSMINUS_Gen(res,u,v);
682}
683static BOOLEAN jjPLUS_P_MA(leftv res, leftv u, leftv v)
684{
685  return jjPLUS_MA_P(res,v,u);
686}
687static BOOLEAN jjPLUS_S(leftv res, leftv u, leftv v)
688{
689  char*    a = (char * )(u->Data());
690  char*    b = (char * )(v->Data());
691  char*    r = (char * )omAlloc(strlen(a) + strlen(b) + 1);
692  strcpy(r,a);
693  strcat(r,b);
694  res->data=r;
695  return jjPLUSMINUS_Gen(res,u,v);
696}
697static BOOLEAN jjPLUS_ID(leftv res, leftv u, leftv v)
698{
699  res->data = (char *)idAdd((ideal)u->Data(),(ideal)v->Data());
700  return jjPLUSMINUS_Gen(res,u,v);
701}
702static BOOLEAN jjMINUS_I(leftv res, leftv u, leftv v)
703{
704  void *ap=u->Data(); void *bp=v->Data();
705  int aa=(int)(long)ap;
706  int bb=(int)(long)bp;
707  int cc=aa-bb;
708  unsigned int a=(unsigned int)(unsigned long)ap;
709  unsigned int b=(unsigned int)(unsigned long)bp;
710  unsigned int c=a-b;
711  if (((Sy_bit(31)&a)!=(Sy_bit(31)&b))&&((Sy_bit(31)&a)!=(Sy_bit(31)&c)))
712  {
713    WarnS("int overflow(-), result may be wrong");
714  }
715  res->data = (char *)((long)cc);
716  return jjPLUSMINUS_Gen(res,u,v);
717}
718static BOOLEAN jjMINUS_BI(leftv res, leftv u, leftv v)
719{
720  res->data = (char *)(nlSub((number)u->Data(), (number)v->Data()));
721  return jjPLUSMINUS_Gen(res,u,v);
722}
723static BOOLEAN jjMINUS_N(leftv res, leftv u, leftv v)
724{
725  res->data = (char *)(nSub((number)u->Data(), (number)v->Data()));
726  return jjPLUSMINUS_Gen(res,u,v);
727}
728static BOOLEAN jjMINUS_P(leftv res, leftv u, leftv v)
729{
730  res->data = (char *)(pSub((poly)u->CopyD(POLY_CMD) , (poly)v->CopyD(POLY_CMD)));
731  return jjPLUSMINUS_Gen(res,u,v);
732}
733static BOOLEAN jjMINUS_IV(leftv res, leftv u, leftv v)
734{
735  res->data = (char *)ivSub((intvec*)(u->Data()), (intvec*)(v->Data()));
736  if (res->data==NULL)
737  {
738     WerrorS("intmat size not compatible");
739     return TRUE;
740  }
741  return jjPLUSMINUS_Gen(res,u,v);
742}
743static BOOLEAN jjMINUS_MA(leftv res, leftv u, leftv v)
744{
745  matrix A=(matrix)u->Data(); matrix B=(matrix)v->Data();
746  res->data = (char *)(mpSub(A , B));
747  if (res->data==NULL)
748  {
749     Werror("matrix size not compatible(%dx%d, %dx%d)",
750             MATROWS(A),MATCOLS(A),MATROWS(B),MATCOLS(B));
751     return TRUE;
752  }
753  return jjPLUSMINUS_Gen(res,u,v);
754  return FALSE;
755}
756static BOOLEAN jjTIMES_I(leftv res, leftv u, leftv v)
757{
758  int a=(int)(long)u->Data();
759  int b=(int)(long)v->Data();
760  int c=a * b;
761  if ((b!=0) && (c/b !=a))
762    WarnS("int overflow(*), result may be wrong");
763  res->data = (char *)((long)c);
764  if ((u->Next()!=NULL) || (v->Next()!=NULL))
765    return jjOP_REST(res,u,v);
766  return FALSE;
767}
768static BOOLEAN jjTIMES_BI(leftv res, leftv u, leftv v)
769{
770  res->data = (char *)(nlMult( (number)u->Data(), (number)v->Data()));
771  if ((v->next!=NULL) || (u->next!=NULL))
772    return jjOP_REST(res,u,v);
773  return FALSE;
774}
775static BOOLEAN jjTIMES_N(leftv res, leftv u, leftv v)
776{
777  res->data = (char *)(nMult( (number)u->Data(), (number)v->Data()));
778  number n=(number)res->data;
779  nNormalize(n);
780  res->data=(char *)n;
781  if ((v->next!=NULL) || (u->next!=NULL))
782    return jjOP_REST(res,u,v);
783  return FALSE;
784}
785static BOOLEAN jjTIMES_P(leftv res, leftv u, leftv v)
786{
787  poly a;
788  poly b;
789  int dummy;
790  if (v->next==NULL)
791  {
792    a=(poly)u->CopyD(POLY_CMD); // works also for VECTOR_CMD
793    if (u->next==NULL)
794    {
795      b=(poly)v->CopyD(POLY_CMD); // works also for VECTOR_CMD
796      if ((a!=NULL) && (b!=NULL)
797      && (pTotaldegree(a)+pTotaldegree(b)>si_max((long)rVar(currRing),(long)currRing->bitmask)))
798      {
799        Werror("OVERFLOW in mult(d=%ld, d=%ld, max=%ld)",
800          pTotaldegree(a),pTotaldegree(b),currRing->bitmask);
801        pDelete(&a);
802        pDelete(&b);
803        return TRUE;
804      }
805      res->data = (char *)(pMult( a, b));
806      pNormalize((poly)res->data);
807      return FALSE;
808    }
809    // u->next exists: copy v
810    b=pCopy((poly)v->Data());
811    if ((a!=NULL) && (b!=NULL)
812    && (pTotaldegree(a)+pTotaldegree(b)>si_max((long)rVar(currRing),(long)currRing->bitmask)))
813    {
814      Werror("OVERFLOW in mult(d=%ld, d=%ld, max=%ld)",
815          pTotaldegree(a),pTotaldegree(b),currRing->bitmask);
816      pDelete(&a);
817      pDelete(&b);
818      return TRUE;
819    }
820    res->data = (char *)(pMult( a, b));
821    pNormalize((poly)res->data);
822    return jjOP_REST(res,u,v);
823  }
824  // v->next exists: copy u
825  a=pCopy((poly)u->Data());
826  b=(poly)v->CopyD(POLY_CMD); // works also for VECTOR_CMD
827  if ((a!=NULL) && (b!=NULL)
828  && ((unsigned long)(pTotaldegree(a)+pTotaldegree(b))>=currRing->bitmask))
829  {
830    pDelete(&a);
831    pDelete(&b);
832    WerrorS("OVERFLOW");
833    return TRUE;
834  }
835  res->data = (char *)(pMult( a, b));
836  pNormalize((poly)res->data);
837  return jjOP_REST(res,u,v);
838}
839static BOOLEAN jjTIMES_ID(leftv res, leftv u, leftv v)
840{
841  res->data = (char *)idMult((ideal)u->Data(),(ideal)v->Data());
842  idNormalize((ideal)res->data);
843  if ((v->next!=NULL) || (u->next!=NULL))
844    return jjOP_REST(res,u,v);
845  return FALSE;
846}
847static BOOLEAN jjTIMES_IV(leftv res, leftv u, leftv v)
848{
849  res->data = (char *)ivMult((intvec*)(u->Data()), (intvec*)(v->Data()));
850  if (res->data==NULL)
851  {
852     WerrorS("intmat size not compatible");
853     return TRUE;
854  }
855  if ((v->next!=NULL) || (u->next!=NULL))
856    return jjOP_REST(res,u,v);
857  return FALSE;
858}
859static BOOLEAN jjTIMES_MA_BI1(leftv res, leftv u, leftv v)
860{
861  number n=nInit_bigint((number)v->Data());
862  poly p=pNSet(n);
863  ideal I= (ideal)mpMultP((matrix)u->CopyD(MATRIX_CMD),p);
864  res->data = (char *)I;
865  return FALSE;
866}
867static BOOLEAN jjTIMES_MA_BI2(leftv res, leftv u, leftv v)
868{
869  return jjTIMES_MA_BI1(res,v,u);
870}
871static BOOLEAN jjTIMES_MA_P1(leftv res, leftv u, leftv v)
872{
873  poly p=(poly)v->CopyD(POLY_CMD);
874  int r=pMaxComp(p);/* recompute the rank for the case ideal*vector*/
875  ideal I= (ideal)mpMultP((matrix)u->CopyD(MATRIX_CMD),p);
876  if (r>0) I->rank=r;
877  idNormalize(I);
878  res->data = (char *)I;
879  return FALSE;
880}
881static BOOLEAN jjTIMES_MA_P2(leftv res, leftv u, leftv v)
882{
883  poly p=(poly)u->CopyD(POLY_CMD);
884  int r=pMaxComp(p);/* recompute the rank for the case ideal*vector*/
885  ideal I= (ideal)pMultMp(p,(matrix)v->CopyD(MATRIX_CMD));
886  if (r>0) I->rank=r;
887  idNormalize(I);
888  res->data = (char *)I;
889  return FALSE;
890}
891static BOOLEAN jjTIMES_MA_N1(leftv res, leftv u, leftv v)
892{
893  number n=(number)v->CopyD(NUMBER_CMD);
894  poly p=pNSet(n);
895  res->data = (char *)mpMultP((matrix)u->CopyD(MATRIX_CMD),p);
896  idNormalize((ideal)res->data);
897  return FALSE;
898}
899static BOOLEAN jjTIMES_MA_N2(leftv res, leftv u, leftv v)
900{
901  return jjTIMES_MA_N1(res,v,u);
902}
903static BOOLEAN jjTIMES_MA_I1(leftv res, leftv u, leftv v)
904{
905  res->data = (char *)mpMultI((matrix)u->CopyD(MATRIX_CMD),(int)(long)v->Data());
906  idNormalize((ideal)res->data);
907  return FALSE;
908}
909static BOOLEAN jjTIMES_MA_I2(leftv res, leftv u, leftv v)
910{
911  return jjTIMES_MA_I1(res,v,u);
912}
913static BOOLEAN jjTIMES_MA(leftv res, leftv u, leftv v)
914{
915  matrix A=(matrix)u->Data(); matrix B=(matrix)v->Data();
916  res->data = (char *)mpMult(A,B);
917  if (res->data==NULL)
918  {
919     Werror("matrix size not compatible(%dx%d, %dx%d)",
920             MATROWS(A),MATCOLS(A),MATROWS(B),MATCOLS(B));
921     return TRUE;
922  }
923  idNormalize((ideal)res->data);
924  if ((v->next!=NULL) || (u->next!=NULL))
925    return jjOP_REST(res,u,v);
926  return FALSE;
927}
928static BOOLEAN jjGE_BI(leftv res, leftv u, leftv v)
929{
930  number h=nlSub((number)u->Data(),(number)v->Data());
931  res->data = (char *) (nlGreaterZero(h)||(nlIsZero(h)));
932  nlDelete(&h,NULL);
933  return FALSE;
934}
935static BOOLEAN jjGE_I(leftv res, leftv u, leftv v)
936{
937  res->data = (char *)((int)((long)u->Data()) >= (int)((long)v->Data()));
938  return FALSE;
939}
940static BOOLEAN jjGE_N(leftv res, leftv u, leftv v)
941{
942  res->data = (char *) (nGreater((number)u->Data(),(number)v->Data())
943                       || nEqual((number)u->Data(),(number)v->Data()));
944  return FALSE;
945}
946static BOOLEAN jjGT_BI(leftv res, leftv u, leftv v)
947{
948  number h=nlSub((number)u->Data(),(number)v->Data());
949  res->data = (char *) (nlGreaterZero(h)&&(!nlIsZero(h)));
950  nlDelete(&h,NULL);
951  return FALSE;
952}
953static BOOLEAN jjGT_I(leftv res, leftv u, leftv v)
954{
955  res->data = (char *)((int)((long)u->Data()) > (int)((long)v->Data()));
956  return FALSE;
957}
958static BOOLEAN jjGT_N(leftv res, leftv u, leftv v)
959{
960  res->data = (char *) (nGreater((number)u->Data(),(number)v->Data()));
961  return FALSE;
962}
963static BOOLEAN jjLE_BI(leftv res, leftv u, leftv v)
964{
965  return jjGE_BI(res,v,u);
966}
967static BOOLEAN jjLE_I(leftv res, leftv u, leftv v)
968{
969  res->data = (char *)((int)((long)u->Data()) <= (int)((long)v->Data()));
970  return FALSE;
971}
972static BOOLEAN jjLE_N(leftv res, leftv u, leftv v)
973{
974  return jjGE_N(res,v,u);
975}
976static BOOLEAN jjLT_BI(leftv res, leftv u, leftv v)
977{
978  return jjGT_BI(res,v,u);
979}
980static BOOLEAN jjLT_I(leftv res, leftv u, leftv v)
981{
982  res->data = (char *)((int)((long)u->Data()) < (int)((long)v->Data()));
983  return FALSE;
984}
985static BOOLEAN jjLT_N(leftv res, leftv u, leftv v)
986{
987  return jjGT_N(res,v,u);
988}
989static BOOLEAN jjDIVMOD_I(leftv res, leftv u, leftv v)
990{
991  int a= (int)(long)u->Data();
992  int b= (int)(long)v->Data();
993  if (b==0)
994  {
995    WerrorS(ii_div_by_0);
996    return TRUE;
997  }
998  int bb=ABS(b);
999  int c=a%bb;
1000  if(c<0) c+=bb;
1001  int r=0;
1002  switch (iiOp)
1003  {
1004    case INTMOD_CMD:
1005        r=c;            break;
1006    case '%':
1007        r= (a % b);     break;
1008    case INTDIV_CMD:
1009        r=((a-c) /b);   break;
1010    case '/':
1011        r= (a / b);     break;
1012  }
1013  res->data=(void *)((long)r);
1014  return FALSE;
1015}
1016static BOOLEAN jjDIV_BI(leftv res, leftv u, leftv v)
1017{
1018  number q=(number)v->Data();
1019  if (nlIsZero(q))
1020  {
1021    WerrorS(ii_div_by_0);
1022    return TRUE;
1023  }
1024  q = nlIntDiv((number)u->Data(),q);
1025  nlNormalize(q);
1026  res->data = (char *)q;
1027  return FALSE;
1028}
1029static BOOLEAN jjDIV_N(leftv res, leftv u, leftv v)
1030{
1031  number q=(number)v->Data();
1032  if (nIsZero(q))
1033  {
1034    WerrorS(ii_div_by_0);
1035    return TRUE;
1036  }
1037  q = nDiv((number)u->Data(),q);
1038  nNormalize(q);
1039  res->data = (char *)q;
1040  return FALSE;
1041}
1042static BOOLEAN jjDIV_P(leftv res, leftv u, leftv v)
1043{
1044  poly q=(poly)v->Data();
1045  if (q==NULL)
1046  {
1047    WerrorS(ii_div_by_0);
1048    return TRUE;
1049  }
1050  poly p=(poly)(u->Data());
1051  if (p==NULL)
1052  {
1053    res->data=NULL;
1054    return FALSE;
1055  }
1056  if ((pNext(q)!=NULL) && (!rField_is_Ring()))
1057  { /* This means that q != 0 consists of at least two terms.
1058       Moreover, currRing is over a field. */
1059#ifdef HAVE_FACTORY
1060    if(pGetComp(p)==0)
1061    {
1062      res->data=(void*)(singclap_pdivide(p /*(poly)(u->Data())*/ ,
1063                                         q /*(poly)(v->Data())*/ ));
1064    }
1065    else
1066    {
1067      int comps=pMaxComp(p);
1068      ideal I=idInit(comps,1);
1069      p=pCopy(p);
1070      poly h;
1071      int i;
1072      // conversion to a list of polys:
1073      while (p!=NULL)
1074      {
1075        i=pGetComp(p)-1;
1076        h=pNext(p);
1077        pNext(p)=NULL;
1078        pSetComp(p,0);
1079        I->m[i]=pAdd(I->m[i],p);
1080        p=h;
1081      }
1082      // division and conversion to vector:
1083      h=NULL;
1084      p=NULL;
1085      for(i=comps-1;i>=0;i--)
1086      {
1087        if (I->m[i]!=NULL)
1088        {
1089          h=singclap_pdivide(I->m[i],q);
1090          pSetCompP(h,i+1);
1091          p=pAdd(p,h);
1092        }
1093      }
1094      idDelete(&I);
1095      res->data=(void *)p;
1096    }
1097#else /* HAVE_FACTORY */
1098    WerrorS("division only by a monomial");
1099    return TRUE;
1100#endif /* HAVE_FACTORY */
1101  }
1102  else
1103  { /* This means that q != 0 consists of just one term,
1104       or that currRing is over a coefficient ring. */
1105#ifdef HAVE_RINGS
1106    if (!rField_is_Domain())
1107    {
1108      WerrorS("division only defined over coefficient domains");
1109      return TRUE;
1110    }
1111    if (pNext(q)!=NULL)
1112    {
1113      WerrorS("division over a coefficient domain only implemented for terms");
1114      return TRUE;
1115    }
1116#endif
1117    res->data = (char *)pDivideM(pCopy(p),pHead(q));
1118  }
1119  pNormalize((poly)res->data);
1120  return FALSE;
1121}
1122static BOOLEAN jjDIV_Ma(leftv res, leftv u, leftv v)
1123{
1124  poly q=(poly)v->Data();
1125  if (q==NULL)
1126  {
1127    WerrorS(ii_div_by_0);
1128    return TRUE;
1129  }
1130  matrix m=(matrix)(u->Data());
1131  int r=m->rows();
1132  int c=m->cols();
1133  matrix mm=mpNew(r,c);
1134  int i,j;
1135  for(i=r;i>0;i--)
1136  {
1137    for(j=c;j>0;j--)
1138    {
1139      if (pNext(q)!=NULL)
1140      {
1141      #ifdef HAVE_FACTORY
1142        MATELEM(mm,i,j) = singclap_pdivide( MATELEM(m,i,j) ,
1143                                           q /*(poly)(v->Data())*/ );
1144#else /* HAVE_FACTORY */
1145        WerrorS("division only by a monomial");
1146        return TRUE;
1147#endif /* HAVE_FACTORY */
1148      }
1149      else
1150        MATELEM(mm,i,j) = pDivideM(pCopy(MATELEM(m,i,j)),pHead(q));
1151    }
1152  }
1153  idNormalize((ideal)mm);
1154  res->data=(char *)mm;
1155  return FALSE;
1156}
1157static BOOLEAN jjEQUAL_BI(leftv res, leftv u, leftv v)
1158{
1159  res->data = (char *)((long)nlEqual((number)u->Data(),(number)v->Data()));
1160  jjEQUAL_REST(res,u,v);
1161  return FALSE;
1162}
1163static BOOLEAN jjEQUAL_I(leftv res, leftv u, leftv v)
1164{
1165  res->data = (char *)((int)((long)u->Data()) == (int)((long)v->Data()));
1166  jjEQUAL_REST(res,u,v);
1167  return FALSE;
1168}
1169static BOOLEAN jjEQUAL_Ma(leftv res, leftv u, leftv v)
1170{
1171  res->data = (char *)((long)mpEqual((matrix)u->Data(),(matrix)v->Data()));
1172  jjEQUAL_REST(res,u,v);
1173  return FALSE;
1174}
1175static BOOLEAN jjEQUAL_N(leftv res, leftv u, leftv v)
1176{
1177  res->data = (char *)((long)nEqual((number)u->Data(),(number)v->Data()));
1178  jjEQUAL_REST(res,u,v);
1179  return FALSE;
1180}
1181static BOOLEAN jjEQUAL_P(leftv res, leftv u, leftv v)
1182{
1183  poly p=(poly)u->Data();
1184  poly q=(poly)v->Data();
1185  res->data = (char *) ((long)pEqualPolys(p,q));
1186  jjEQUAL_REST(res,u,v);
1187  return FALSE;
1188}
1189static void jjEQUAL_REST(leftv res,leftv u,leftv v)
1190{
1191  if ((res->data) && (u->next!=NULL) && (v->next!=NULL))
1192  {
1193    int save_iiOp=iiOp;
1194    if (iiOp==NOTEQUAL)
1195      iiExprArith2(res,u->next,EQUAL_EQUAL,v->next);
1196    else
1197      iiExprArith2(res,u->next,iiOp,v->next);
1198    iiOp=save_iiOp;
1199  }
1200  if (iiOp==NOTEQUAL) res->data=(char *)(!(long)res->data);
1201}
1202static BOOLEAN jjAND_I(leftv res, leftv u, leftv v)
1203{
1204  res->data = (char *)((long)u->Data() && (long)v->Data());
1205  return FALSE;
1206}
1207static BOOLEAN jjOR_I(leftv res, leftv u, leftv v)
1208{
1209  res->data = (char *)((long)u->Data() || (long)v->Data());
1210  return FALSE;
1211}
1212static BOOLEAN jjINDEX_I(leftv res, leftv u, leftv v)
1213{
1214  res->rtyp=u->rtyp; u->rtyp=0;
1215  res->data=u->data; u->data=NULL;
1216  res->name=u->name; u->name=NULL;
1217  res->attribute=u->attribute; u->attribute=NULL;
1218  res->e=u->e;       u->e=NULL;
1219  if (res->e==NULL) res->e=jjMakeSub(v);
1220  else
1221  {
1222    Subexpr sh=res->e;
1223    while (sh->next != NULL) sh=sh->next;
1224    sh->next=jjMakeSub(v);
1225  }
1226  return FALSE;
1227}
1228static BOOLEAN jjINDEX_IV(leftv res, leftv u, leftv v)
1229{
1230  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
1231  {
1232    WerrorS("indexed object must have a name");
1233    return TRUE;
1234  }
1235  intvec * iv=(intvec *)v->Data();
1236  leftv p=NULL;
1237  int i;
1238  sleftv t;
1239  memset(&t,0,sizeof(t));
1240  t.rtyp=INT_CMD;
1241  for (i=0;i<iv->length(); i++)
1242  {
1243    t.data=(char *)((long)(*iv)[i]);
1244    if (p==NULL)
1245    {
1246      p=res;
1247    }
1248    else
1249    {
1250      p->next=(leftv)omAlloc0Bin(sleftv_bin);
1251      p=p->next;
1252    }
1253    p->rtyp=IDHDL;
1254    p->data=u->data;
1255    p->name=u->name;
1256    p->flag=u->flag;
1257    p->attribute=u->attribute;
1258    p->e=jjMakeSub(&t);
1259  }
1260  u->rtyp=0;
1261  u->data=NULL;
1262  u->name=NULL;
1263  return FALSE;
1264}
1265static BOOLEAN jjINDEX_P(leftv res, leftv u, leftv v)
1266{
1267  poly p=(poly)u->Data();
1268  int i=(int)(long)v->Data();
1269  int j=0;
1270  while (p!=NULL)
1271  {
1272    j++;
1273    if (j==i)
1274    {
1275      res->data=(char *)pHead(p);
1276      return FALSE;
1277    }
1278    pIter(p);
1279  }
1280  return FALSE;
1281}
1282static BOOLEAN jjINDEX_P_IV(leftv res, leftv u, leftv v)
1283{
1284  poly p=(poly)u->Data();
1285  poly r=NULL;
1286  intvec *iv=(intvec *)v->CopyD(INTVEC_CMD);
1287  int i;
1288  int sum=0;
1289  for(i=iv->length()-1;i>=0;i--)
1290    sum+=(*iv)[i];
1291  int j=0;
1292  while ((p!=NULL) && (sum>0))
1293  {
1294    j++;
1295    for(i=iv->length()-1;i>=0;i--)
1296    {
1297      if (j==(*iv)[i])
1298      {
1299        r=pAdd(r,pHead(p));
1300        sum-=j;
1301        (*iv)[i]=0;
1302        break;
1303      }
1304    }
1305    pIter(p);
1306  }
1307  delete iv;
1308  res->data=(char *)r;
1309  return FALSE;
1310}
1311static BOOLEAN jjINDEX_V(leftv res, leftv u, leftv v)
1312{
1313  poly p=(poly)u->CopyD(VECTOR_CMD);
1314  poly r=p; // pointer to the beginning of component i
1315  poly o=NULL;
1316  int i=(int)(long)v->Data();
1317  while (p!=NULL)
1318  {
1319    if (pGetComp(p)!=i)
1320    {
1321      if (r==p) r=pNext(p);
1322      if (o!=NULL)
1323      {
1324        if (pNext(o)!=NULL) pLmDelete(&pNext(o));
1325        p=pNext(o);
1326      }
1327      else
1328        pLmDelete(&p);
1329    }
1330    else
1331    {
1332      pSetComp(p, 0);
1333      p_SetmComp(p, currRing);
1334      o=p;
1335      p=pNext(o);
1336    }
1337  }
1338  res->data=(char *)r;
1339  return FALSE;
1340}
1341static BOOLEAN jjINDEX_V_IV(leftv res, leftv u, leftv v)
1342{
1343  poly p=(poly)u->CopyD(VECTOR_CMD);
1344  if (p!=NULL)
1345  {
1346    poly r=pOne();
1347    poly hp=r;
1348    intvec *iv=(intvec *)v->Data();
1349    int i;
1350    loop
1351    {
1352      for(i=0;i<iv->length();i++)
1353      {
1354        if (pGetComp(p)==(*iv)[i])
1355        {
1356          poly h;
1357          pSplit(p,&h);
1358          pNext(hp)=p;
1359          p=h;
1360          pIter(hp);
1361          break;
1362        }
1363      }
1364      if (p==NULL) break;
1365      if (i==iv->length())
1366      {
1367        pLmDelete(&p);
1368        if (p==NULL) break;
1369      }
1370    }
1371    pLmDelete(&r);
1372    res->data=(char *)r;
1373  }
1374  return FALSE;
1375}
1376static BOOLEAN jjKLAMMER_rest(leftv res, leftv u, leftv v);
1377static BOOLEAN jjKLAMMER(leftv res, leftv u, leftv v)
1378{
1379  if(u->name==NULL) return TRUE;
1380  char * nn = (char *)omAlloc(strlen(u->name) + 14);
1381  sprintf(nn,"%s(%d)",u->name,(int)(long)v->Data());
1382  omFree((ADDRESS)u->name);
1383  u->name=NULL;
1384  char *n=omStrDup(nn);
1385  omFree((ADDRESS)nn);
1386  syMake(res,n);
1387  if (u->next!=NULL) return jjKLAMMER_rest(res,u->next,v);
1388  return FALSE;
1389}
1390static BOOLEAN jjKLAMMER_IV(leftv res, leftv u, leftv v)
1391{
1392  intvec * iv=(intvec *)v->Data();
1393  leftv p=NULL;
1394  int i;
1395  long slen = strlen(u->name) + 14;
1396  char *n = (char*) omAlloc(slen);
1397
1398  for (i=0;i<iv->length(); i++)
1399  {
1400    if (p==NULL)
1401    {
1402      p=res;
1403    }
1404    else
1405    {
1406      p->next=(leftv)omAlloc0Bin(sleftv_bin);
1407      p=p->next;
1408    }
1409    sprintf(n,"%s(%d)",u->name,(*iv)[i]);
1410    syMake(p,omStrDup(n));
1411  }
1412  omFree((ADDRESS)u->name);
1413  u->name = NULL;
1414  omFreeSize(n, slen);
1415  if (u->next!=NULL) return jjKLAMMER_rest(res,u->next,v);
1416  return FALSE;
1417}
1418static BOOLEAN jjKLAMMER_rest(leftv res, leftv u, leftv v)
1419{
1420  leftv tmp=(leftv)omAllocBin(sleftv_bin);
1421  memset(tmp,0,sizeof(sleftv));
1422  BOOLEAN b;
1423  if (v->Typ()==INTVEC_CMD)
1424    b=jjKLAMMER_IV(tmp,u,v);
1425  else
1426    b=jjKLAMMER(tmp,u,v);
1427  if (b)
1428  {
1429    omFreeBin(tmp,sleftv_bin);
1430    return TRUE;
1431  }
1432  leftv h=res;
1433  while (h->next!=NULL) h=h->next;
1434  h->next=tmp;
1435  return FALSE;
1436}
1437BOOLEAN jjPROC(leftv res, leftv u, leftv v)
1438{
1439  void *d;
1440  Subexpr e;
1441  int typ;
1442  BOOLEAN t=FALSE;
1443  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
1444  {
1445    idrec tmp_proc;
1446    tmp_proc.id="_auto";
1447    tmp_proc.typ=PROC_CMD;
1448    tmp_proc.data.pinf=(procinfo *)u->Data();
1449    tmp_proc.ref=1;
1450    d=u->data; u->data=(void *)&tmp_proc;
1451    e=u->e; u->e=NULL;
1452    t=TRUE;
1453    typ=u->rtyp; u->rtyp=IDHDL;
1454  }
1455  leftv sl;
1456  if (u->req_packhdl==currPack)
1457    sl = iiMake_proc((idhdl)u->data,NULL,v);
1458  else
1459    sl = iiMake_proc((idhdl)u->data,u->req_packhdl,v);
1460  if (t)
1461  {
1462    u->rtyp=typ;
1463    u->data=d;
1464    u->e=e;
1465  }
1466  if (sl==NULL)
1467  {
1468    return TRUE;
1469  }
1470  else
1471  {
1472    memcpy(res,sl,sizeof(sleftv));
1473  }
1474  return FALSE;
1475}
1476static BOOLEAN jjMAP(leftv res, leftv u, leftv v)
1477{
1478  //Print("try to map %s with %s\n",$3.Name(),$1.Name());
1479  leftv sl=NULL;
1480  if ((v->e==NULL)&&(v->name!=NULL))
1481  {
1482    map m=(map)u->Data();
1483    sl=iiMap(m,v->name);
1484  }
1485  else
1486  {
1487    Werror("%s(<name>) expected",u->Name());
1488  }
1489  if (sl==NULL) return TRUE;
1490  memcpy(res,sl,sizeof(sleftv));
1491  omFreeBin((ADDRESS)sl, sleftv_bin);
1492  return FALSE;
1493}
1494static BOOLEAN jjCALL2MANY(leftv res, leftv u, leftv v)
1495{
1496  u->next=(leftv)omAllocBin(sleftv_bin);
1497  memcpy(u->next,v,sizeof(sleftv));
1498  BOOLEAN r=iiExprArithM(res,u,iiOp);
1499  v->Init();
1500  // iiExprArithM did the CleanUp
1501  return r;
1502}
1503#ifdef HAVE_FACTORY
1504static BOOLEAN jjCHINREM_BI(leftv res, leftv u, leftv v)
1505{
1506  if (rField_is_Q())
1507  {
1508    intvec *c=(intvec*)u->Data();
1509    intvec* p=(intvec*)v->Data();
1510    int rl=p->length();
1511    number *x=(number *)omAlloc(rl*sizeof(number));
1512    number *q=(number *)omAlloc(rl*sizeof(number));
1513    int i;
1514    for(i=rl-1;i>=0;i--)
1515    {
1516      q[i]=nlInit((*p)[i], NULL);
1517      x[i]=nlInit((*c)[i], NULL);
1518    }
1519    number n=nlChineseRemainder(x,q,rl);
1520    for(i=rl-1;i>=0;i--)
1521    {
1522      nlDelete(&(q[i]),NULL);
1523      nlDelete(&(x[i]),NULL);
1524    }
1525    omFree(x); omFree(q);
1526    res->data=(char *)n;
1527    return FALSE;
1528  }
1529  else return TRUE;
1530}
1531#endif
1532#if 0
1533static BOOLEAN jjCHINREM_P(leftv res, leftv u, leftv v)
1534{
1535  lists c=(lists)u->CopyD(); // list of poly
1536  intvec* p=(intvec*)v->Data();
1537  int rl=p->length();
1538  poly r=NULL,h, result=NULL;
1539  number *x=(number *)omAlloc(rl*sizeof(number));
1540  number *q=(number *)omAlloc(rl*sizeof(number));
1541  int i;
1542  for(i=rl-1;i>=0;i--)
1543  {
1544    q[i]=nlInit((*p)[i]);
1545  }
1546  loop
1547  {
1548    for(i=rl-1;i>=0;i--)
1549    {
1550      if (c->m[i].Typ()!=POLY_CMD)
1551      {
1552        Werror("poly expected at pos %d",i+1);
1553        for(i=rl-1;i>=0;i--)
1554        {
1555          nlDelete(&(q[i]),currRing);
1556        }
1557        omFree(x); omFree(q); // delete c
1558        return TRUE;
1559      }
1560      h=((poly)c->m[i].Data());
1561      if (r==NULL) r=h;
1562      else if (pLmCmp(r,h)==-1) r=h;
1563    }
1564    if (r==NULL) break;
1565    for(i=rl-1;i>=0;i--)
1566    {
1567      h=((poly)c->m[i].Data());
1568      if (pLmCmp(r,h)==0)
1569      {
1570        x[i]=pGetCoeff(h);
1571        h=pLmFreeAndNext(h);
1572        c->m[i].data=(char*)h;
1573      }
1574      else
1575        x[i]=nlInit(0);
1576    }
1577    number n=nlChineseRemainder(x,q,rl);
1578    for(i=rl-1;i>=0;i--)
1579    {
1580      nlDelete(&(x[i]),currRing);
1581    }
1582    h=pHead(r);
1583    pSetCoeff(h,n);
1584    result=pAdd(result,h);
1585  }
1586  for(i=rl-1;i>=0;i--)
1587  {
1588    nlDelete(&(q[i]),currRing);
1589  }
1590  omFree(x); omFree(q);
1591  res->data=(char *)result;
1592  return FALSE;
1593}
1594#endif
1595#ifdef HAVE_FACTORY
1596static BOOLEAN jjCHINREM_ID(leftv res, leftv u, leftv v)
1597{
1598  if (rField_is_Q())
1599  {
1600    lists c=(lists)u->CopyD(); // list of ideal
1601    lists pl=NULL;
1602    intvec *p=NULL;
1603    if (v->Typ()==LIST_CMD) pl=(lists)v->Data();
1604    else                    p=(intvec*)v->Data();
1605    int rl=c->nr+1;
1606    poly r=NULL,h;
1607    ideal result;
1608    ideal *x=(ideal *)omAlloc(rl*sizeof(ideal));
1609    int i;
1610    int return_type=c->m[0].Typ();
1611    if ((return_type!=IDEAL_CMD)
1612    && (return_type!=MODUL_CMD)
1613    && (return_type!=MATRIX_CMD))
1614    {
1615      WerrorS("ideal/module/matrix expected");
1616      omFree(x); // delete c
1617      return TRUE;
1618    }
1619    for(i=rl-1;i>=0;i--)
1620    {
1621      if (c->m[i].Typ()!=return_type)
1622      {
1623        Werror("%s expected at pos %d",Tok2Cmdname(return_type),i+1);
1624        omFree(x); // delete c
1625        return TRUE;
1626      }
1627      x[i]=((ideal)c->m[i].Data());
1628    }
1629    number *q=(number *)omAlloc(rl*sizeof(number));
1630    if (p!=NULL)
1631    {
1632      for(i=rl-1;i>=0;i--)
1633      {
1634        q[i]=nlInit((*p)[i], currRing);
1635      }
1636    }
1637    else
1638    {
1639      for(i=rl-1;i>=0;i--)
1640      {
1641        if (pl->m[i].Typ()==INT_CMD)
1642        {
1643          q[i]=nlInit((int)(long)pl->m[i].Data(),currRing);
1644        }
1645        else if (pl->m[i].Typ()==BIGINT_CMD)
1646        {
1647          q[i]=nlCopy((number)(pl->m[i].Data()));
1648        }
1649        else
1650        {
1651          Werror("bigint expected at pos %d",i+1);
1652          for(i++;i<rl;i++)
1653          {
1654            nlDelete(&(q[i]),currRing);
1655          }
1656          omFree(x); // delete c
1657          omFree(q); // delete pl
1658          return TRUE;
1659        }
1660      }
1661    }
1662    result=idChineseRemainder(x,q,rl);
1663    for(i=rl-1;i>=0;i--)
1664    {
1665      nlDelete(&(q[i]),currRing);
1666    }
1667    omFree(q);
1668    res->data=(char *)result;
1669    res->rtyp=return_type;
1670    return FALSE;
1671  }
1672  else return TRUE;
1673}
1674#endif
1675static BOOLEAN jjCOEF(leftv res, leftv u, leftv v)
1676{
1677  poly p=(poly)v->Data();
1678  if ((p==NULL)||(pNext(p)!=NULL)) return TRUE;
1679  res->data=(char *)mpCoeffProc((poly)u->Data(),p /*(poly)v->Data()*/);
1680  return FALSE;
1681}
1682static BOOLEAN jjCOEFFS_Id(leftv res, leftv u, leftv v)
1683{
1684  int i=pVar((poly)v->Data());
1685  if (i==0)
1686  {
1687    WerrorS("ringvar expected");
1688    return TRUE;
1689  }
1690  res->data=(char *)mpCoeffs((ideal)u->CopyD(),i);
1691  return FALSE;
1692}
1693static BOOLEAN jjCOEFFS2_KB(leftv res, leftv u, leftv v)
1694{
1695  poly p = pInit();
1696  int i;
1697  for (i=1; i<=pVariables; i++)
1698  {
1699    pSetExp(p, i, 1);
1700  }
1701  pSetm(p);
1702  res->data = (void*)idCoeffOfKBase((ideal)(u->Data()),
1703                                    (ideal)(v->Data()), p);
1704  pDelete(&p);
1705  return FALSE;
1706}
1707static BOOLEAN jjCONTRACT(leftv res, leftv u, leftv v)
1708{
1709  res->data=(char *)idDiffOp((ideal)u->Data(),(ideal)v->Data(),FALSE);
1710  return FALSE;
1711}
1712static BOOLEAN jjDEG_M_IV(leftv res, leftv u, leftv v)
1713{
1714  short *iv=iv2array((intvec *)v->Data());
1715  ideal I=(ideal)u->Data();
1716  int d=-1;
1717  int i;
1718  for(i=IDELEMS(I);i>=0;i--) d=si_max(d,(int)pDegW(I->m[i],iv));
1719  omFreeSize((ADDRESS)iv,(pVariables+1)*sizeof(short));
1720  res->data = (char *)((long)d);
1721  return FALSE;
1722}
1723static BOOLEAN jjDEG_IV(leftv res, leftv u, leftv v)
1724{
1725  poly p=(poly)u->Data();
1726  if (p!=NULL)
1727  {
1728    short *iv=iv2array((intvec *)v->Data());
1729    int d=(int)pDegW(p,iv);
1730    omFreeSize((ADDRESS)iv,(pVariables+1)*sizeof(short));
1731    res->data = (char *)(long(d));
1732  }
1733  else
1734    res->data=(char *)(long)(-1);
1735  return FALSE;
1736}
1737static BOOLEAN jjDIFF_P(leftv res, leftv u, leftv v)
1738{
1739  int i=pVar((poly)v->Data());
1740  if (i==0)
1741  {
1742    WerrorS("ringvar expected");
1743    return TRUE;
1744  }
1745  res->data=(char *)pDiff((poly)(u->Data()),i);
1746  return FALSE;
1747}
1748static BOOLEAN jjDIFF_ID(leftv res, leftv u, leftv v)
1749{
1750  int i=pVar((poly)v->Data());
1751  if (i==0)
1752  {
1753    WerrorS("ringvar expected");
1754    return TRUE;
1755  }
1756  res->data=(char *)idDiff((matrix)(u->Data()),i);
1757  return FALSE;
1758}
1759static BOOLEAN jjDIFF_ID_ID(leftv res, leftv u, leftv v)
1760{
1761  res->data=(char *)idDiffOp((ideal)u->Data(),(ideal)v->Data());
1762  return FALSE;
1763}
1764static BOOLEAN jjDIM2(leftv res, leftv v, leftv w)
1765{
1766  assumeStdFlag(v);
1767  if(currQuotient==NULL)
1768    res->data = (char *)((long)scDimInt((ideal)(v->Data()),(ideal)w->Data()));
1769  else
1770  {
1771    ideal q=idSimpleAdd(currQuotient,(ideal)w->Data());
1772    res->data = (char *)((long)scDimInt((ideal)(v->Data()),q));
1773    idDelete(&q);
1774  }
1775  return FALSE;
1776}
1777static BOOLEAN jjDIVISION(leftv res, leftv u, leftv v)
1778{
1779  ideal vi=(ideal)v->Data();
1780  int vl= IDELEMS(vi);
1781  ideal ui=(ideal)u->Data();
1782  int ul= IDELEMS(ui);
1783  ideal R; matrix U;
1784  ideal m = idLift(vi,ui,&R, FALSE,hasFlag(v,FLAG_STD),TRUE,&U);
1785  // now make sure that all matices have the corect size:
1786  matrix T = idModule2formatedMatrix(m,vl,ul);
1787  int i;
1788  if (MATCOLS(U) != ul)
1789  {
1790    int mul=si_min(ul,MATCOLS(U));
1791    matrix UU=mpNew(ul,ul);
1792    int j;
1793    for(i=mul;i>0;i--)
1794    {
1795      for(j=mul;j>0;j--)
1796      {
1797        MATELEM(UU,i,j)=MATELEM(U,i,j);
1798        MATELEM(U,i,j)=NULL;
1799      }
1800    }
1801    idDelete((ideal *)&U);
1802    U=UU;
1803  }
1804  // make sure that U is a diagonal matrix of units
1805  for(i=ul;i>0;i--)
1806  {
1807    if(MATELEM(U,i,i)==NULL) MATELEM(U,i,i)=pOne();
1808  }
1809  lists L=(lists)omAllocBin(slists_bin);
1810  L->Init(3);
1811  L->m[0].rtyp=MATRIX_CMD;   L->m[0].data=(void *)T;
1812  L->m[1].rtyp=u->Typ();     L->m[1].data=(void *)R;
1813  L->m[2].rtyp=MATRIX_CMD;   L->m[2].data=(void *)U;
1814  res->data=(char *)L;
1815  return FALSE;
1816}
1817static BOOLEAN jjELIMIN(leftv res, leftv u, leftv v)
1818{
1819  res->data=(char *)idElimination((ideal)u->Data(),(poly)v->Data());
1820  //setFlag(res,FLAG_STD);
1821  return FALSE;
1822}
1823static BOOLEAN jjELIMIN_IV(leftv res, leftv u, leftv v)
1824{
1825  poly p=pOne();
1826  intvec *iv=(intvec*)v->Data();
1827  for(int i=iv->length()-1; i>=0; i--)
1828  {
1829    pSetExp(p,(*iv)[i],1);
1830  }
1831  pSetm(p);
1832  res->data=(char *)idElimination((ideal)u->Data(),p);
1833  pLmDelete(&p);
1834  //setFlag(res,FLAG_STD);
1835  return FALSE;
1836}
1837static BOOLEAN jjEXPORTTO(leftv res, leftv u, leftv v)
1838{
1839  //Print("exportto %s -> %s\n",v->Name(),u->Name() );
1840  return iiExport(v,0,(idhdl)u->data);
1841}
1842static BOOLEAN jjERROR(leftv res, leftv u)
1843{
1844  WerrorS((char *)u->Data());
1845  extern int inerror;
1846  inerror=3;
1847  return TRUE;
1848}
1849static BOOLEAN jjEXTGCD_I(leftv res, leftv u, leftv v)
1850{
1851  int uu=(int)(long)u->Data();int vv=(int)(long)v->Data();
1852  int p0=ABS(uu),p1=ABS(vv);
1853  int f0 = 1, f1 = 0, g0 = 0, g1 = 1, q, r;
1854
1855  while ( p1!=0 )
1856  {
1857    q=p0 / p1;
1858    r=p0 % p1;
1859    p0 = p1; p1 = r;
1860    r = g0 - g1 * q;
1861    g0 = g1; g1 = r;
1862    r = f0 - f1 * q;
1863    f0 = f1; f1 = r;
1864  }
1865  int a = f0;
1866  int b = g0;
1867  if ( uu /*(int)(long)u->Data()*/ < 0 ) a=-a;
1868  if ( vv /*(int)(long)v->Data()*/ < 0 ) b=-b;
1869  lists L=(lists)omAllocBin(slists_bin);
1870  L->Init(3);
1871  L->m[0].rtyp=INT_CMD;   L->m[0].data=(void *)(long)p0;
1872  L->m[1].rtyp=INT_CMD;   L->m[1].data=(void *)(long)a;
1873  L->m[2].rtyp=INT_CMD;   L->m[2].data=(void *)(long)b;
1874  res->rtyp=LIST_CMD;
1875  res->data=(char *)L;
1876  return FALSE;
1877}
1878#ifdef HAVE_FACTORY
1879static BOOLEAN jjEXTGCD_P(leftv res, leftv u, leftv v)
1880{
1881  poly r,pa,pb;
1882  BOOLEAN ret=singclap_extgcd((poly)u->Data(),(poly)v->Data(),r,pa,pb);
1883  if (ret) return TRUE;
1884  lists L=(lists)omAllocBin(slists_bin);
1885  L->Init(3);
1886  res->data=(char *)L;
1887  L->m[0].data=(void *)r;
1888  L->m[0].rtyp=POLY_CMD;
1889  L->m[1].data=(void *)pa;
1890  L->m[1].rtyp=POLY_CMD;
1891  L->m[2].data=(void *)pb;
1892  L->m[2].rtyp=POLY_CMD;
1893  return FALSE;
1894}
1895extern int singclap_factorize_retry;
1896static BOOLEAN jjFAC_P2(leftv res, leftv u,leftv dummy)
1897{
1898  intvec *v=NULL;
1899  int sw=(int)(long)dummy->Data();
1900  int fac_sw=sw;
1901  if ((sw<0)||(sw>2)) fac_sw=1;
1902  singclap_factorize_retry=0;
1903  ideal f=singclap_factorize((poly)(u->CopyD()), &v, fac_sw);
1904  if (f==NULL)
1905    return TRUE;
1906  switch(sw)
1907  {
1908    case 0:
1909    case 2:
1910    {
1911      lists l=(lists)omAllocBin(slists_bin);
1912      l->Init(2);
1913      l->m[0].rtyp=IDEAL_CMD;
1914      l->m[0].data=(void *)f;
1915      l->m[1].rtyp=INTVEC_CMD;
1916      l->m[1].data=(void *)v;
1917      res->data=(void *)l;
1918      res->rtyp=LIST_CMD;
1919      return FALSE;
1920    }
1921    case 1:
1922      res->data=(void *)f;
1923      return FALSE;
1924    case 3:
1925      {
1926        poly p=f->m[0];
1927        int i=IDELEMS(f);
1928        f->m[0]=NULL;
1929        while(i>1)
1930        {
1931          i--;
1932          p=pMult(p,f->m[i]);
1933          f->m[i]=NULL;
1934        }
1935        res->data=(void *)p;
1936        res->rtyp=POLY_CMD;
1937      }
1938      return FALSE;
1939  }
1940  WerrorS("invalid switch");
1941  return TRUE;
1942}
1943static BOOLEAN jjFACSTD2(leftv res, leftv v, leftv w)
1944{
1945  ideal_list p,h;
1946  h=kStdfac((ideal)v->Data(),NULL,testHomog,NULL,(ideal)w->Data());
1947  p=h;
1948  int l=0;
1949  while (p!=NULL) { p=p->next;l++; }
1950  lists L=(lists)omAllocBin(slists_bin);
1951  L->Init(l);
1952  l=0;
1953  while(h!=NULL)
1954  {
1955    L->m[l].data=(char *)h->d;
1956    L->m[l].rtyp=IDEAL_CMD;
1957    p=h->next;
1958    omFreeSize(h,sizeof(*h));
1959    h=p;
1960    l++;
1961  }
1962  res->data=(void *)L;
1963  return FALSE;
1964}
1965#endif /* HAVE_FACTORY */
1966static BOOLEAN jjFAREY_BI(leftv res, leftv u, leftv v)
1967{
1968  if (rField_is_Q())
1969  {
1970    number uu=(number)u->Data();
1971    number vv=(number)v->Data();
1972    res->data=(char *)nlFarey(uu,vv);
1973    return FALSE;
1974  }
1975  else return TRUE;
1976}
1977static BOOLEAN jjFAREY_ID(leftv res, leftv u, leftv v)
1978{
1979  if (rField_is_Q())
1980  {
1981    ideal uu=(ideal)u->Data();
1982    number vv=(number)v->Data();
1983    res->data=(void*)idFarey(uu,vv);
1984    res->rtyp=u->Typ();
1985    return FALSE;
1986  }
1987  else return TRUE;
1988}
1989static BOOLEAN jjFETCH(leftv res, leftv u, leftv v)
1990{
1991  ring r=(ring)u->Data();
1992  idhdl w;
1993  int op=iiOp;
1994  nMapFunc nMap;
1995
1996  if ((w=r->idroot->get(v->Name(),myynest))!=NULL)
1997  {
1998    int *perm=NULL;
1999    int *par_perm=NULL;
2000    int par_perm_size=0;
2001    BOOLEAN bo;
2002    //if (!nSetMap(rInternalChar(r),r->parameter,rPar(r),r->minpoly))
2003    if ((nMap=nSetMap(r))==NULL)
2004    {
2005      if (rEqual(r,currRing))
2006      {
2007        nMap=nCopy;
2008      }
2009      else
2010      // Allow imap/fetch to be make an exception only for:
2011      if ( (rField_is_Q_a(r) &&  // Q(a..) -> Q(a..) || Q || Zp || Zp(a)
2012            (rField_is_Q() || rField_is_Q_a() ||
2013             (rField_is_Zp() || rField_is_Zp_a())))
2014           ||
2015           (rField_is_Zp_a(r) &&  // Zp(a..) -> Zp(a..) || Zp
2016            (rField_is_Zp(currRing, rInternalChar(r)) ||
2017             rField_is_Zp_a(currRing, rInternalChar(r)))) )
2018      {
2019        par_perm_size=rPar(r);
2020        BITSET save_test=test;
2021        naSetChar(rInternalChar(r),r);
2022        nSetChar(currRing);
2023        test=save_test;
2024      }
2025      else
2026      {
2027        goto err_fetch;
2028      }
2029    }
2030    if ((iiOp!=FETCH_CMD) || (r->N!=pVariables) || (rPar(r)!=rPar(currRing)))
2031    {
2032      perm=(int *)omAlloc0((r->N+1)*sizeof(int));
2033      if (par_perm_size!=0)
2034        par_perm=(int *)omAlloc0(par_perm_size*sizeof(int));
2035      op=IMAP_CMD;
2036      if (iiOp==IMAP_CMD)
2037      {
2038        maFindPerm(r->names,       r->N,       r->parameter,        r->P,
2039                   currRing->names,currRing->N,currRing->parameter, currRing->P,
2040                   perm,par_perm, currRing->ch);
2041      }
2042      else
2043      {
2044        int i;
2045        if (par_perm_size!=0)
2046          for(i=si_min(rPar(r),rPar(currRing))-1;i>=0;i--) par_perm[i]=-(i+1);
2047        for(i=si_min(r->N,pVariables);i>0;i--) perm[i]=i;
2048      }
2049    }
2050    if ((iiOp==FETCH_CMD) &&(BVERBOSE(V_IMAP)))
2051    {
2052      int i;
2053      for(i=0;i<si_min(r->N,pVariables);i++)
2054      {
2055        Print("// var nr %d: %s -> %s\n",i,r->names[i],currRing->names[i]);
2056      }
2057      for(i=0;i<si_min(rPar(r),rPar(currRing));i++) // possibly empty loop
2058      {
2059        Print("// par nr %d: %s -> %s\n",
2060              i,r->parameter[i],currRing->parameter[i]);
2061      }
2062    }
2063    sleftv tmpW;
2064    memset(&tmpW,0,sizeof(sleftv));
2065    tmpW.rtyp=IDTYP(w);
2066    tmpW.data=IDDATA(w);
2067    if ((bo=maApplyFetch(op,NULL,res,&tmpW, r,
2068                         perm,par_perm,par_perm_size,nMap)))
2069    {
2070      Werror("cannot map %s of type %s(%d)",v->name, Tok2Cmdname(w->typ),w->typ);
2071    }
2072    if (perm!=NULL)
2073      omFreeSize((ADDRESS)perm,(r->N+1)*sizeof(int));
2074    if (par_perm!=NULL)
2075      omFreeSize((ADDRESS)par_perm,par_perm_size*sizeof(int));
2076    return bo;
2077  }
2078  else
2079  {
2080    Werror("identifier %s not found in %s",v->Fullname(),u->Fullname());
2081  }
2082  return TRUE;
2083err_fetch:
2084  Werror("no identity map from %s",u->Fullname());
2085  return TRUE;
2086}
2087static BOOLEAN jjFIND2(leftv res, leftv u, leftv v)
2088{
2089  /*4
2090  * look for the substring what in the string where
2091  * return the position of the first char of what in where
2092  * or 0
2093  */
2094  char *where=(char *)u->Data();
2095  char *what=(char *)v->Data();
2096  char *found = strstr(where,what);
2097  if (found != NULL)
2098  {
2099    res->data=(char *)((found-where)+1);
2100  }
2101  /*else res->data=NULL;*/
2102  return FALSE;
2103}
2104static BOOLEAN jjFWALK(leftv res, leftv u, leftv v)
2105{
2106  res->data=(char *)fractalWalkProc(u,v);
2107  setFlag( res, FLAG_STD );
2108  return FALSE;
2109}
2110static BOOLEAN jjGCD_I(leftv res, leftv u, leftv v)
2111{
2112  int uu=(int)(long)u->Data();int vv=(int)(long)v->Data();
2113  int p0=ABS(uu),p1=ABS(vv);
2114  int r;
2115  while ( p1!=0 )
2116  {
2117    r=p0 % p1;
2118    p0 = p1; p1 = r;
2119  }
2120  res->rtyp=INT_CMD;
2121  res->data=(char *)(long)p0;
2122  return FALSE;
2123}
2124static BOOLEAN jjGCD_BI(leftv res, leftv u, leftv v)
2125{
2126  number a=(number) u->Data();
2127  number b=(number) v->Data();
2128  if (nlIsZero(a))
2129  {
2130    if (nlIsZero(b)) res->data=(char *)nlInit(1, NULL);
2131    else             res->data=(char *)nlCopy(b);
2132  }
2133  else
2134  {
2135    if (nlIsZero(b))  res->data=(char *)nlCopy(a);
2136    else res->data=(char *)nlGcd(a, b, NULL);
2137  }
2138  return FALSE;
2139}
2140static BOOLEAN jjGCD_N(leftv res, leftv u, leftv v)
2141{
2142  number a=(number) u->Data();
2143  number b=(number) v->Data();
2144  if (nIsZero(a))
2145  {
2146    if (nIsZero(b)) res->data=(char *)nInit(1);
2147    else            res->data=(char *)nCopy(b);
2148  }
2149  else
2150  {
2151    if (nIsZero(b))  res->data=(char *)nCopy(a);
2152    else res->data=(char *)nGcd(a, b, currRing);
2153  }
2154  return FALSE;
2155}
2156#ifdef HAVE_FACTORY
2157static BOOLEAN jjGCD_P(leftv res, leftv u, leftv v)
2158{
2159  res->data=(void *)singclap_gcd((poly)(u->CopyD(POLY_CMD)),
2160                                 (poly)(v->CopyD(POLY_CMD)));
2161  return FALSE;
2162}
2163#endif /* HAVE_FACTORY */
2164static BOOLEAN jjHILBERT2(leftv res, leftv u, leftv v)
2165{
2166  assumeStdFlag(u);
2167  intvec *module_w=(intvec*)atGet(u,"isHomog",INTVEC_CMD);
2168  intvec *iv=hFirstSeries((ideal)u->Data(),module_w,currQuotient);
2169  switch((int)(long)v->Data())
2170  {
2171    case 1:
2172      res->data=(void *)iv;
2173      return FALSE;
2174    case 2:
2175      res->data=(void *)hSecondSeries(iv);
2176      delete iv;
2177      return FALSE;
2178  }
2179  WerrorS(feNotImplemented);
2180  delete iv;
2181  return TRUE;
2182}
2183static BOOLEAN jjHOMOG_P(leftv res, leftv u, leftv v)
2184{
2185  int i=pVar((poly)v->Data());
2186  if (i==0)
2187  {
2188    WerrorS("ringvar expected");
2189    return TRUE;
2190  }
2191  poly p=pOne(); pSetExp(p,i,1); pSetm(p);
2192  int d=pWTotaldegree(p);
2193  pLmDelete(p);
2194  if (d==1)
2195    res->data = (char *)pHomogen((poly)u->Data(),i);
2196  else
2197    WerrorS("variable must have weight 1");
2198  return (d!=1);
2199}
2200static BOOLEAN jjHOMOG_ID(leftv res, leftv u, leftv v)
2201{
2202  int i=pVar((poly)v->Data());
2203  if (i==0)
2204  {
2205    WerrorS("ringvar expected");
2206    return TRUE;
2207  }
2208  pFDegProc deg;
2209  if (pLexOrder && (currRing->order[0]==ringorder_lp))
2210    deg=p_Totaldegree;
2211   else
2212    deg=pFDeg;
2213  poly p=pOne(); pSetExp(p,i,1); pSetm(p);
2214  int d=deg(p,currRing);
2215  pLmDelete(p);
2216  if (d==1)
2217    res->data = (char *)idHomogen((ideal)u->Data(),i);
2218  else
2219    WerrorS("variable must have weight 1");
2220  return (d!=1);
2221}
2222static BOOLEAN jjHOMOG1_W(leftv res, leftv v, leftv u)
2223{
2224  intvec *w=new intvec(rVar(currRing));
2225  intvec *vw=(intvec*)u->Data();
2226  ideal v_id=(ideal)v->Data();
2227  pFDegProc save_FDeg=pFDeg;
2228  pLDegProc save_LDeg=pLDeg;
2229  BOOLEAN save_pLexOrder=pLexOrder;
2230  pLexOrder=FALSE;
2231  kHomW=vw;
2232  kModW=w;
2233  pSetDegProcs(kHomModDeg);
2234  res->data=(void *)(long)idHomModule(v_id,currQuotient,&w);
2235  pLexOrder=save_pLexOrder;
2236  kHomW=NULL;
2237  kModW=NULL;
2238  pRestoreDegProcs(save_FDeg,save_LDeg);
2239  if (w!=NULL) delete w;
2240  return FALSE;
2241}
2242static BOOLEAN jjINDEPSET2(leftv res, leftv u, leftv v)
2243{
2244  assumeStdFlag(u);
2245  res->data=(void *)scIndIndset((ideal)(u->Data()),(int)(long)(v->Data()),
2246                    currQuotient);
2247  return FALSE;
2248}
2249static BOOLEAN jjINTERSECT(leftv res, leftv u, leftv v)
2250{
2251  res->data=(char *)idSect((ideal)u->Data(),(ideal)v->Data());
2252  setFlag(res,FLAG_STD);
2253  return FALSE;
2254}
2255static BOOLEAN jjJanetBasis2(leftv res, leftv u, leftv v)
2256{
2257  return jjStdJanetBasis(res,u,(int)(long)v->Data());
2258}
2259static BOOLEAN jjJET_P(leftv res, leftv u, leftv v)
2260{
2261  res->data = (char *)pJet((poly)u->CopyD(), (int)(long)v->Data());
2262  return FALSE;
2263}
2264static BOOLEAN jjJET_ID(leftv res, leftv u, leftv v)
2265{
2266  res->data = (char *)idJet((ideal)u->Data(),(int)(long)v->Data());
2267  return FALSE;
2268}
2269static BOOLEAN jjKBASE2(leftv res, leftv u, leftv v)
2270{
2271  assumeStdFlag(u);
2272  intvec *w_u=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
2273  res->data = (char *)scKBase((int)(long)v->Data(),
2274                              (ideal)(u->Data()),currQuotient, w_u);
2275  if (w_u!=NULL)
2276  {
2277    atSet(res,omStrDup("isHomog"),ivCopy(w_u),INTVEC_CMD);
2278  }
2279  return FALSE;
2280}
2281static BOOLEAN jjPREIMAGE(leftv res, leftv u, leftv v, leftv w);
2282static BOOLEAN jjKERNEL(leftv res, leftv u, leftv v)
2283{
2284  return jjPREIMAGE(res,u,v,NULL);
2285}
2286static BOOLEAN jjKoszul(leftv res, leftv u, leftv v)
2287{
2288  return mpKoszul(res, u,v);
2289}
2290static BOOLEAN jjKoszul_Id(leftv res, leftv u, leftv v)
2291{
2292  sleftv h;
2293  memset(&h,0,sizeof(sleftv));
2294  h.rtyp=INT_CMD;
2295  h.data=(void *)(long)IDELEMS((ideal)v->Data());
2296  return mpKoszul(res, u, &h, v);
2297}
2298static BOOLEAN jjLIFT(leftv res, leftv u, leftv v)
2299{
2300  ideal m;
2301  BITSET save_test=test;
2302  int ul= IDELEMS((ideal)u->Data());
2303  int vl= IDELEMS((ideal)v->Data());
2304  m = idLift((ideal)u->Data(),(ideal)v->Data(),NULL,FALSE,hasFlag(u,FLAG_STD));
2305  res->data = (char *)idModule2formatedMatrix(m,ul,vl);
2306  test=save_test;
2307  return FALSE;
2308}
2309static BOOLEAN jjLIFTSTD(leftv res, leftv u, leftv v)
2310{
2311  if ((v->rtyp!=IDHDL)||(v->e!=NULL)) return TRUE;
2312  idhdl h=(idhdl)v->data;
2313  // CopyD for IDEAL_CMD and MODUL_CMD are identical:
2314  res->data = (char *)idLiftStd((ideal)u->Data(),
2315                                &(h->data.umatrix),testHomog);
2316  setFlag(res,FLAG_STD); v->flag=0;
2317  return FALSE;
2318}
2319static BOOLEAN jjLOAD2(leftv res, leftv u,leftv v)
2320{
2321  return jjLOAD(res, v,TRUE);
2322}
2323static BOOLEAN jjLOAD_E(leftv res, leftv v, leftv u)
2324{
2325  char * s=(char *)u->Data();
2326  if(strcmp(s, "with")==0)
2327    return jjLOAD(res, v, TRUE);
2328  WerrorS("invalid second argument");
2329  WerrorS("load(\"libname\" [,\"with\"]);");
2330  return TRUE;
2331}
2332static BOOLEAN jjMODULO(leftv res, leftv u, leftv v)
2333{
2334  intvec *w_u=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
2335  tHomog hom=testHomog;
2336  if (w_u!=NULL)
2337  {
2338    w_u=ivCopy(w_u);
2339    hom=isHomog;
2340  }
2341  intvec *w_v=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
2342  if (w_v!=NULL)
2343  {
2344    w_v=ivCopy(w_v);
2345    hom=isHomog;
2346  }
2347  if ((w_u!=NULL) && (w_v==NULL))
2348    w_v=ivCopy(w_u);
2349  if ((w_v!=NULL) && (w_u==NULL))
2350    w_u=ivCopy(w_v);
2351  ideal u_id=(ideal)u->Data();
2352  ideal v_id=(ideal)v->Data();
2353  if (w_u!=NULL)
2354  {
2355     if ((*w_u).compare((w_v))!=0)
2356     {
2357       WarnS("incompatible weights");
2358       delete w_u; w_u=NULL;
2359       hom=testHomog;
2360     }
2361     else
2362     {
2363       if ((!idTestHomModule(u_id,currQuotient,w_v))
2364       || (!idTestHomModule(v_id,currQuotient,w_v)))
2365       {
2366         WarnS("wrong weights");
2367         delete w_u; w_u=NULL;
2368         hom=testHomog;
2369       }
2370     }
2371  }
2372  res->data = (char *)idModulo(u_id,v_id ,hom,&w_u);
2373  if (w_u!=NULL)
2374  {
2375    atSet(res,omStrDup("isHomog"),w_u,INTVEC_CMD);
2376  }
2377  delete w_v;
2378  return FALSE;
2379}
2380static BOOLEAN jjMOD_BI(leftv res, leftv u, leftv v)
2381{
2382  number q=(number)v->Data();
2383  if (nlIsZero(q))
2384  {
2385    WerrorS(ii_div_by_0);
2386    return TRUE;
2387  }
2388  res->data =(char *) nlIntMod((number)u->Data(),q);
2389  return FALSE;
2390}
2391static BOOLEAN jjMOD_N(leftv res, leftv u, leftv v)
2392{
2393  number q=(number)v->Data();
2394  if (nIsZero(q))
2395  {
2396    WerrorS(ii_div_by_0);
2397    return TRUE;
2398  }
2399  res->data =(char *) nIntMod((number)u->Data(),q);
2400  return FALSE;
2401}
2402static BOOLEAN jjMONITOR2(leftv res, leftv u,leftv v);
2403static BOOLEAN jjMONITOR1(leftv res, leftv v)
2404{
2405  return jjMONITOR2(res,v,NULL);
2406}
2407static BOOLEAN jjMONITOR2(leftv res, leftv u,leftv v)
2408{
2409#if 0
2410  char *opt=(char *)v->Data();
2411  int mode=0;
2412  while(*opt!='\0')
2413  {
2414    if (*opt=='i') mode |= PROT_I;
2415    else if (*opt=='o') mode |= PROT_O;
2416    opt++;
2417  }
2418  monitor((char *)(u->Data()),mode);
2419#else
2420  si_link l=(si_link)u->Data();
2421  if (slOpen(l,SI_LINK_WRITE,u)) return TRUE;
2422  if(strcmp(l->m->type,"ASCII")!=0)
2423  {
2424    Werror("ASCII link required, not `%s`",l->m->type);
2425    slClose(l);
2426    return TRUE;
2427  }
2428  SI_LINK_SET_CLOSE_P(l); // febase handles the FILE*
2429  if ( l->name[0]!='\0') // "" is the stop condition
2430  {
2431    const char *opt;
2432    int mode=0;
2433    if (v==NULL) opt=(const char*)"i";
2434    else         opt=(const char *)v->Data();
2435    while(*opt!='\0')
2436    {
2437      if (*opt=='i') mode |= PROT_I;
2438      else if (*opt=='o') mode |= PROT_O;
2439      opt++;
2440    }
2441    monitor((FILE *)l->data,mode);
2442  }
2443  else
2444    monitor(NULL,0);
2445  return FALSE;
2446#endif
2447}
2448static BOOLEAN jjMONOM(leftv res, leftv v)
2449{
2450  intvec *iv=(intvec *)v->Data();
2451  poly p=pOne();
2452  int i,e;
2453  BOOLEAN err=FALSE;
2454  for(i=si_min(pVariables,iv->length()); i>0; i--)
2455  {
2456    e=(*iv)[i-1];
2457    if (e>=0) pSetExp(p,i,e);
2458    else err=TRUE;
2459  }
2460  if (iv->length()==(pVariables+1))
2461  {
2462    res->rtyp=VECTOR_CMD;
2463    e=(*iv)[pVariables];
2464    if (e>=0) pSetComp(p,e);
2465    else err=TRUE;
2466  }
2467  pSetm(p);
2468  res->data=(char*)p;
2469  if(err) { pDelete(&p); WerrorS("no negative exponent allowed"); }
2470  return err;
2471}
2472static BOOLEAN jjNEWSTRUCT2(leftv res, leftv u, leftv v)
2473{
2474  // u: the name of the new type
2475  // v: the elements
2476  newstruct_desc d=newstructFromString((const char *)v->Data());
2477  if (d!=NULL) newstruct_setup((const char *)u->Data(),d);
2478  return d==NULL;
2479}
2480static BOOLEAN jjPARSTR2(leftv res, leftv u, leftv v)
2481{
2482  idhdl h=(idhdl)u->data;
2483  int i=(int)(long)v->Data();
2484  int p=0;
2485  if ((0<i)
2486  && (IDRING(h)->parameter!=NULL)
2487  && (i<=(p=rPar(IDRING(h)))))
2488    res->data=omStrDup(IDRING(h)->parameter[i-1]);
2489  else
2490  {
2491    Werror("par number %d out of range 1..%d",i,p);
2492    return TRUE;
2493  }
2494  return FALSE;
2495}
2496#ifdef HAVE_PLURAL
2497static BOOLEAN jjPlural_num_poly(leftv res, leftv a, leftv b)
2498{
2499  if( currRing->qideal != NULL )
2500  {
2501    WerrorS("basering must NOT be a qring!");
2502    return TRUE;
2503  }
2504
2505  if (iiOp==NCALGEBRA_CMD)
2506  {
2507    return nc_CallPlural(NULL,NULL,(poly)a->Data(),(poly)b->Data(),currRing);
2508  }
2509  else
2510  {
2511    ring r=rCopy(currRing);
2512    BOOLEAN result=nc_CallPlural(NULL,NULL,(poly)a->Data(),(poly)b->Data(),r);
2513    res->data=r;
2514    if (r->qideal!=NULL) res->rtyp=QRING_CMD;
2515    return result;
2516  }
2517}
2518static BOOLEAN jjPlural_num_mat(leftv res, leftv a, leftv b)
2519{
2520  if( currRing->qideal != NULL )
2521  {
2522    WerrorS("basering must NOT be a qring!");
2523    return TRUE;
2524  }
2525
2526  if (iiOp==NCALGEBRA_CMD)
2527  {
2528    return nc_CallPlural(NULL,(matrix)b->Data(),(poly)a->Data(),NULL,currRing);
2529  }
2530  else
2531  {
2532    ring r=rCopy(currRing);
2533    BOOLEAN result=nc_CallPlural(NULL,(matrix)b->Data(),(poly)a->Data(),NULL,r);
2534    res->data=r;
2535    if (r->qideal!=NULL) res->rtyp=QRING_CMD;
2536    return result;
2537  }
2538}
2539static BOOLEAN jjPlural_mat_poly(leftv res, leftv a, leftv b)
2540{
2541  if( currRing->qideal != NULL )
2542  {
2543    WerrorS("basering must NOT be a qring!");
2544    return TRUE;
2545  }
2546
2547  if (iiOp==NCALGEBRA_CMD)
2548  {
2549    return nc_CallPlural((matrix)a->Data(),NULL,NULL,(poly)b->Data(),currRing);
2550  }
2551  else
2552  {
2553    ring r=rCopy(currRing);
2554    BOOLEAN result=nc_CallPlural((matrix)a->Data(),NULL,NULL,(poly)b->Data(),r);
2555    res->data=r;
2556    if (r->qideal!=NULL) res->rtyp=QRING_CMD;
2557    return result;
2558  }
2559}
2560static BOOLEAN jjPlural_mat_mat(leftv res, leftv a, leftv b)
2561{
2562  if( currRing->qideal != NULL )
2563  {
2564    WerrorS("basering must NOT be a qring!");
2565    return TRUE;
2566  }
2567
2568  if (iiOp==NCALGEBRA_CMD)
2569  {
2570    return nc_CallPlural((matrix)a->Data(),(matrix)b->Data(),NULL,NULL,currRing);
2571  }
2572  else
2573  {
2574    ring r=rCopy(currRing);
2575    BOOLEAN result=nc_CallPlural((matrix)a->Data(),(matrix)b->Data(),NULL,NULL,r);
2576    res->data=r;
2577    if (r->qideal!=NULL) res->rtyp=QRING_CMD;
2578    return result;
2579  }
2580}
2581static BOOLEAN jjBRACKET(leftv res, leftv a, leftv b)
2582{
2583  res->data=NULL;
2584
2585  if (rIsPluralRing(currRing))
2586  {
2587    const poly q = (poly)b->Data();
2588
2589    if( q != NULL )
2590    {
2591      if( (poly)a->Data() != NULL )
2592      {
2593        poly p = (poly)a->CopyD(POLY_CMD); // p = copy!
2594        res->data = nc_p_Bracket_qq(p,q); // p will be destroyed!
2595      }
2596    }
2597  }
2598  return FALSE;
2599}
2600static BOOLEAN jjOPPOSE(leftv res, leftv a, leftv b)
2601{
2602  /* number, poly, vector, ideal, module, matrix */
2603  ring  r = (ring)a->Data();
2604  if (r == currRing)
2605  {
2606    res->data = b->Data();
2607    res->rtyp = b->rtyp;
2608    return FALSE;
2609  }
2610  if (!rIsLikeOpposite(currRing, r))
2611  {
2612    Werror("%s is not an opposite ring to current ring",a->Fullname());
2613    return TRUE;
2614  }
2615  idhdl w;
2616  if( ((w=r->idroot->get(b->Name(),myynest))!=NULL) && (b->e==NULL))
2617  {
2618    int argtype = IDTYP(w);
2619    switch (argtype)
2620    {
2621    case NUMBER_CMD:
2622      {
2623        /* since basefields are equal, we can apply nCopy */
2624        res->data = nCopy((number)IDDATA(w));
2625        res->rtyp = argtype;
2626        break;
2627      }
2628    case POLY_CMD:
2629    case VECTOR_CMD:
2630      {
2631        poly    q = (poly)IDDATA(w);
2632        res->data = pOppose(r,q);
2633        res->rtyp = argtype;
2634        break;
2635      }
2636    case IDEAL_CMD:
2637    case MODUL_CMD:
2638      {
2639        ideal   Q = (ideal)IDDATA(w);
2640        res->data = idOppose(r,Q);
2641        res->rtyp = argtype;
2642        break;
2643      }
2644    case MATRIX_CMD:
2645      {
2646        ring save = currRing;
2647        rChangeCurrRing(r);
2648        matrix  m = (matrix)IDDATA(w);
2649        ideal   Q = idMatrix2Module(mpCopy(m));
2650        rChangeCurrRing(save);
2651        ideal   S = idOppose(r,Q);
2652        id_Delete(&Q, r);
2653        res->data = idModule2Matrix(S);
2654        res->rtyp = argtype;
2655        break;
2656      }
2657    default:
2658      {
2659        WerrorS("unsupported type in oppose");
2660        return TRUE;
2661      }
2662    }
2663  }
2664  else
2665  {
2666    Werror("identifier %s not found in %s",b->Fullname(),a->Fullname());
2667    return TRUE;
2668  }
2669  return FALSE;
2670}
2671#endif /* HAVE_PLURAL */
2672
2673static BOOLEAN jjQUOT(leftv res, leftv u, leftv v)
2674{
2675  res->data = (char *)idQuot((ideal)u->Data(),(ideal)v->Data(),
2676    hasFlag(u,FLAG_STD),u->Typ()==v->Typ());
2677  idDelMultiples((ideal)(res->data));
2678  return FALSE;
2679}
2680static BOOLEAN jjRANDOM(leftv res, leftv u, leftv v)
2681{
2682  int i=(int)(long)u->Data();
2683  int j=(int)(long)v->Data();
2684  res->data =(char *)(long)((i > j) ? i : (siRand() % (j-i+1)) + i);
2685  return FALSE;
2686}
2687static BOOLEAN jjRANK2(leftv res, leftv u, leftv v)
2688{
2689  matrix m =(matrix)u->Data();
2690  int isRowEchelon = (int)(long)v->Data();
2691  if (isRowEchelon != 1) isRowEchelon = 0;
2692  int rank = luRank(m, isRowEchelon);
2693  res->data =(char *)(long)rank;
2694  return FALSE;
2695}
2696static BOOLEAN jjREAD2(leftv res, leftv u, leftv v)
2697{
2698  si_link l=(si_link)u->Data();
2699  leftv r=slRead(l,v);
2700  if (r==NULL)
2701  {
2702    const char *s;
2703    if ((l!=NULL)&&(l->name!=NULL)) s=l->name;
2704    else                            s=sNoName;
2705    Werror("cannot read from `%s`",s);
2706    return TRUE;
2707  }
2708  memcpy(res,r,sizeof(sleftv));
2709  omFreeBin((ADDRESS)r, sleftv_bin);
2710  return FALSE;
2711}
2712static BOOLEAN jjREDUCE_P(leftv res, leftv u, leftv v)
2713{
2714  assumeStdFlag(v);
2715  res->data = (char *)kNF((ideal)v->Data(),currQuotient,(poly)u->Data());
2716  return FALSE;
2717}
2718static BOOLEAN jjREDUCE_ID(leftv res, leftv u, leftv v)
2719{
2720  assumeStdFlag(v);
2721  ideal ui=(ideal)u->Data();
2722  idTest(ui);
2723  ideal vi=(ideal)v->Data();
2724  idTest(vi);
2725  res->data = (char *)kNF(vi,currQuotient,ui);
2726  return FALSE;
2727}
2728#if 0
2729static BOOLEAN jjRES(leftv res, leftv u, leftv v)
2730{
2731  int maxl=(int)(long)v->Data();
2732  if (maxl<0)
2733  {
2734    WerrorS("length for res must not be negative");
2735    return TRUE;
2736  }
2737  int l=0;
2738  //resolvente r;
2739  syStrategy r;
2740  intvec *weights=NULL;
2741  int wmaxl=maxl;
2742  ideal u_id=(ideal)u->Data();
2743
2744  maxl--;
2745  if ((maxl==-1) /*&& (iiOp!=MRES_CMD)*/)
2746  {
2747    maxl = pVariables-1+2*(iiOp==MRES_CMD);
2748    if (currQuotient!=NULL)
2749    {
2750      Warn(
2751      "full resolution in a qring may be infinite, setting max length to %d",
2752      maxl+1);
2753    }
2754  }
2755  weights=(intvec*)atGet(u,"isHomog",INTVEC_CMD);
2756  if (weights!=NULL)
2757  {
2758    if (!idTestHomModule(u_id,currQuotient,weights))
2759    {
2760      WarnS("wrong weights given:");weights->show();PrintLn();
2761      weights=NULL;
2762    }
2763  }
2764  intvec *ww=NULL;
2765  int add_row_shift=0;
2766  if (weights!=NULL)
2767  {
2768     ww=ivCopy(weights);
2769     add_row_shift = ww->min_in();
2770     (*ww) -= add_row_shift;
2771  }
2772  else
2773    idHomModule(u_id,currQuotient,&ww);
2774  weights=ww;
2775
2776  if ((iiOp == RES_CMD) || (iiOp == MRES_CMD))
2777  {
2778    r=syResolution(u_id,maxl, ww, iiOp==MRES_CMD);
2779  }
2780  else if (iiOp==SRES_CMD)
2781  //  r=sySchreyerResolvente(u_id,maxl+1,&l);
2782    r=sySchreyer(u_id,maxl+1);
2783  else if (iiOp == LRES_CMD)
2784  {
2785    int dummy;
2786    if((currQuotient!=NULL)||
2787    (!idHomIdeal (u_id,NULL)))
2788    {
2789       WerrorS
2790       ("`lres` not implemented for inhomogeneous input or qring");
2791       return TRUE;
2792    }
2793    r=syLaScala3(u_id,&dummy);
2794  }
2795  else if (iiOp == KRES_CMD)
2796  {
2797    int dummy;
2798    if((currQuotient!=NULL)||
2799    (!idHomIdeal (u_id,NULL)))
2800    {
2801       WerrorS
2802       ("`kres` not implemented for inhomogeneous input or qring");
2803       return TRUE;
2804    }
2805    r=syKosz(u_id,&dummy);
2806  }
2807  else
2808  {
2809    int dummy;
2810    if((currQuotient!=NULL)||
2811    (!idHomIdeal (u_id,NULL)))
2812    {
2813       WerrorS
2814       ("`hres` not implemented for inhomogeneous input or qring");
2815       return TRUE;
2816    }
2817    r=syHilb(u_id,&dummy);
2818  }
2819  if (r==NULL) return TRUE;
2820  //res->data=(void *)liMakeResolv(r,l,wmaxl,u->Typ(),weights);
2821  r->list_length=wmaxl;
2822  res->data=(void *)r;
2823  if ((r->weights!=NULL) && (r->weights[0]!=NULL))
2824  {
2825    intvec *w=ivCopy(r->weights[0]);
2826    if (weights!=NULL) (*w) += add_row_shift;
2827    atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
2828    w=NULL;
2829  }
2830  else
2831  {
2832//#if 0
2833// need to set weights for ALL components (sres)
2834    if (weights!=NULL)
2835    {
2836      atSet(res,omStrDup("isHomog"),ivCopy(weights),INTVEC_CMD);
2837      r->weights = (intvec**)omAlloc0Bin(char_ptr_bin);
2838      (r->weights)[0] = ivCopy(weights);
2839    }
2840//#endif
2841  }
2842  if (ww!=NULL) { delete ww; ww=NULL; }
2843  return FALSE;
2844}
2845#else
2846static BOOLEAN jjRES(leftv res, leftv u, leftv v)
2847{
2848  int maxl=(int)(long)v->Data();
2849  if (maxl<0)
2850  {
2851    WerrorS("length for res must not be negative");
2852    return TRUE;
2853  }
2854  int l=0;
2855  //resolvente r;
2856  syStrategy r;
2857  intvec *weights=NULL;
2858  int wmaxl=maxl;
2859  ideal u_id=(ideal)u->Data();
2860
2861  maxl--;
2862  if ((maxl==-1) /*&& (iiOp!=MRES_CMD)*/)
2863  {
2864    maxl = pVariables-1+2*(iiOp==MRES_CMD);
2865    if (currQuotient!=NULL)
2866    {
2867      Warn(
2868      "full resolution in a qring may be infinite, setting max length to %d",
2869      maxl+1);
2870    }
2871  }
2872  weights=(intvec*)atGet(u,"isHomog",INTVEC_CMD);
2873  if (weights!=NULL)
2874  {
2875    if (!idTestHomModule(u_id,currQuotient,weights))
2876    {
2877      WarnS("wrong weights given:");weights->show();PrintLn();
2878      weights=NULL;
2879    }
2880  }
2881  intvec *ww=NULL;
2882  int add_row_shift=0;
2883  if (weights!=NULL)
2884  {
2885     ww=ivCopy(weights);
2886     add_row_shift = ww->min_in();
2887     (*ww) -= add_row_shift;
2888  }
2889  if ((iiOp == RES_CMD) || (iiOp == MRES_CMD))
2890  {
2891    r=syResolution(u_id,maxl, ww, iiOp==MRES_CMD);
2892  }
2893  else if (iiOp==SRES_CMD)
2894  //  r=sySchreyerResolvente(u_id,maxl+1,&l);
2895    r=sySchreyer(u_id,maxl+1);
2896  else if (iiOp == LRES_CMD)
2897  {
2898    int dummy;
2899    if((currQuotient!=NULL)||
2900    (!idHomIdeal (u_id,NULL)))
2901    {
2902       WerrorS
2903       ("`lres` not implemented for inhomogeneous input or qring");
2904       return TRUE;
2905    }
2906    r=syLaScala3(u_id,&dummy);
2907  }
2908  else if (iiOp == KRES_CMD)
2909  {
2910    int dummy;
2911    if((currQuotient!=NULL)||
2912    (!idHomIdeal (u_id,NULL)))
2913    {
2914       WerrorS
2915       ("`kres` not implemented for inhomogeneous input or qring");
2916       return TRUE;
2917    }
2918    r=syKosz(u_id,&dummy);
2919  }
2920  else
2921  {
2922    int dummy;
2923    if((currQuotient!=NULL)||
2924    (!idHomIdeal (u_id,NULL)))
2925    {
2926       WerrorS
2927       ("`hres` not implemented for inhomogeneous input or qring");
2928       return TRUE;
2929    }
2930    ideal u_id_copy=idCopy(u_id);
2931    idSkipZeroes(u_id_copy);
2932    r=syHilb(u_id_copy,&dummy);
2933    idDelete(&u_id_copy);
2934  }
2935  if (r==NULL) return TRUE;
2936  //res->data=(void *)liMakeResolv(r,l,wmaxl,u->Typ(),weights);
2937  r->list_length=wmaxl;
2938  res->data=(void *)r;
2939  if ((weights!=NULL) && (ww!=NULL)) { delete ww; ww=NULL; }
2940  if ((r->weights!=NULL) && (r->weights[0]!=NULL))
2941  {
2942    ww=ivCopy(r->weights[0]);
2943    if (weights!=NULL) (*ww) += add_row_shift;
2944    atSet(res,omStrDup("isHomog"),ww,INTVEC_CMD);
2945  }
2946  else
2947  {
2948    if (weights!=NULL)
2949    {
2950      atSet(res,omStrDup("isHomog"),ivCopy(weights),INTVEC_CMD);
2951    }
2952  }
2953  return FALSE;
2954}
2955#endif
2956static BOOLEAN jjPFAC2(leftv res, leftv u, leftv v)
2957{
2958  number n1; number n2; number temp; int i;
2959
2960  if ((u->Typ() == BIGINT_CMD) ||
2961     ((u->Typ() == NUMBER_CMD) && rField_is_Q()))
2962  {
2963    temp = (number)u->Data();
2964    n1 = nlCopy(temp);
2965  }
2966  else if (u->Typ() == INT_CMD)
2967  {
2968    i = (int)(long)u->Data();
2969    n1 = nlInit(i, NULL);
2970  }
2971  else
2972  {
2973    WerrorS("wrong type: expected int, bigint, or number as 1st argument");
2974    return TRUE;
2975  }
2976
2977  if ((v->Typ() == BIGINT_CMD) ||
2978     ((v->Typ() == NUMBER_CMD) && rField_is_Q()))
2979  {
2980    temp = (number)v->Data();
2981    n2 = nlCopy(temp);
2982  }
2983  else if (v->Typ() == INT_CMD)
2984  {
2985    i = (int)(long)v->Data();
2986    n2 = nlInit(i, NULL);
2987  }
2988  else
2989  {
2990    WerrorS("wrong type: expected int, bigint, or number as 2nd argument");
2991    return TRUE;
2992  }
2993
2994  lists l = primeFactorisation(n1, n2);
2995  nlDelete(&n1, NULL); nlDelete(&n2, NULL);
2996  res->data = (char*)l;
2997  return FALSE;
2998}
2999static BOOLEAN jjRSUM(leftv res, leftv u, leftv v)
3000{
3001  ring r;
3002  int i=rSum((ring)u->Data(),(ring)v->Data(),r);
3003  res->data = (char *)r;
3004  return (i==-1);
3005}
3006#define SIMPL_LMDIV 32
3007#define SIMPL_LMEQ  16
3008#define SIMPL_MULT 8
3009#define SIMPL_EQU  4
3010#define SIMPL_NULL 2
3011#define SIMPL_NORM 1
3012static BOOLEAN jjSIMPL_ID(leftv res, leftv u, leftv v)
3013{
3014  int sw = (int)(long)v->Data();
3015  // CopyD for IDEAL_CMD and MODUL_CMD are identical:
3016  ideal id = (ideal)u->CopyD(IDEAL_CMD);
3017  if (sw & SIMPL_LMDIV)
3018  {
3019    idDelDiv(id);
3020  }
3021  if (sw & SIMPL_LMEQ)
3022  {
3023    idDelLmEquals(id);
3024  }
3025  if (sw & SIMPL_MULT)
3026  {
3027    idDelMultiples(id);
3028  }
3029  else if(sw & SIMPL_EQU)
3030  {
3031    idDelEquals(id);
3032  }
3033  if (sw & SIMPL_NULL)
3034  {
3035    idSkipZeroes(id);
3036  }
3037  if (sw & SIMPL_NORM)
3038  {
3039    idNorm(id);
3040  }
3041  res->data = (char * )id;
3042  return FALSE;
3043}
3044static BOOLEAN jjSTATUS2(leftv res, leftv u, leftv v)
3045{
3046  res->data = omStrDup(slStatus((si_link) u->Data(), (char *) v->Data()));
3047  return FALSE;
3048}
3049static BOOLEAN jjSTATUS2L(leftv res, leftv u, leftv v)
3050{
3051  res->data = (void *)(long)slStatusSsiL((lists) u->Data(), (int)(long) v->Data());
3052  //return (res->data== (void*)(long)-2);
3053  return FALSE;
3054}
3055static BOOLEAN jjSIMPL_P(leftv res, leftv u, leftv v)
3056{
3057  int sw = (int)(long)v->Data();
3058  // CopyD for POLY_CMD and VECTOR_CMD are identical:
3059  poly p = (poly)u->CopyD(POLY_CMD);
3060  if (sw & SIMPL_NORM)
3061  {
3062    pNorm(p);
3063  }
3064  res->data = (char * )p;
3065  return FALSE;
3066}
3067static BOOLEAN jjSTD_HILB(leftv res, leftv u, leftv v)
3068{
3069  ideal result;
3070  intvec *w=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
3071  tHomog hom=testHomog;
3072  ideal u_id=(ideal)(u->Data());
3073  if (w!=NULL)
3074  {
3075    if (!idTestHomModule(u_id,currQuotient,w))
3076    {
3077      WarnS("wrong weights:");w->show();PrintLn();
3078      w=NULL;
3079    }
3080    else
3081    {
3082      w=ivCopy(w);
3083      hom=isHomog;
3084    }
3085  }
3086  result=kStd(u_id,currQuotient,hom,&w,(intvec *)v->Data());
3087  idSkipZeroes(result);
3088  res->data = (char *)result;
3089  setFlag(res,FLAG_STD);
3090  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
3091  return FALSE;
3092}
3093static BOOLEAN jjSTD_1(leftv res, leftv u, leftv v);
3094static void jjSTD_1_ID(leftv res, ideal i0, int t0, ideal p0, attr a)
3095/* destroys i0, p0 */
3096/* result (with attributes) in res */
3097/* i0: SB*/
3098/* t0: type of p0*/
3099/* p0 new elements*/
3100/* a attributes of i0*/
3101{
3102  int tp;
3103  if (t0==IDEAL_CMD) tp=POLY_CMD;
3104  else               tp=VECTOR_CMD;
3105  for (int i=IDELEMS(p0)-1; i>=0; i--)
3106  {
3107    poly p=p0->m[i];
3108    p0->m[i]=NULL;
3109    if (p!=NULL)
3110    {
3111      sleftv u0,v0;
3112      memset(&u0,0,sizeof(sleftv));
3113      memset(&v0,0,sizeof(sleftv));
3114      v0.rtyp=tp;
3115      v0.data=(void*)p;
3116      u0.rtyp=t0;
3117      u0.data=i0;
3118      u0.attribute=a;
3119      setFlag(&u0,FLAG_STD);
3120      jjSTD_1(res,&u0,&v0);
3121      i0=(ideal)res->data;
3122      res->data=NULL;
3123      a=res->attribute;
3124      res->attribute=NULL;
3125      u0.CleanUp();
3126      v0.CleanUp();
3127      res->CleanUp();
3128    }
3129  }
3130  idDelete(&p0);
3131  res->attribute=a;
3132  res->data=(void *)i0;
3133  res->rtyp=t0;
3134}
3135static BOOLEAN jjSTD_1(leftv res, leftv u, leftv v)
3136{
3137  ideal result;
3138  assumeStdFlag(u);
3139  ideal i1=(ideal)(u->Data());
3140  ideal i0;
3141  int r=v->Typ();
3142  if ((/*v->Typ()*/r==POLY_CMD) ||(r==VECTOR_CMD))
3143  {
3144    i0=idInit(1,i1->rank); // TODO: rank is wrong (if v is a vector!)
3145    i0->m[0]=(poly)v->Data();
3146    int ii0=idElem(i0); /* size of i0 */
3147    i1=idSimpleAdd(i1,i0); //
3148    memset(i0->m,0,sizeof(poly)*IDELEMS(i0));
3149    idDelete(&i0);
3150    intvec *w=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
3151    tHomog hom=testHomog;
3152
3153    if (w!=NULL)
3154    {
3155      if (!idTestHomModule(i1,currQuotient,w))
3156      {
3157        // no warnung: this is legal, if i in std(i,p)
3158        // is homogeneous, but p not
3159        w=NULL;
3160      }
3161      else
3162      {
3163        w=ivCopy(w);
3164        hom=isHomog;
3165      }
3166    }
3167    BITSET save_test=test;
3168    test|=Sy_bit(OPT_SB_1);
3169    /* ii0 appears to be the position of the first element of il that
3170       does not belong to the old SB ideal */
3171    result=kStd(i1,currQuotient,hom,&w,NULL,0,ii0);
3172    test=save_test;
3173    idDelete(&i1);
3174    idSkipZeroes(result);
3175    if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
3176    res->data = (char *)result;
3177  }
3178  else /*IDEAL/MODULE*/
3179  {
3180    attr a=NULL;
3181    if (u->attribute!=NULL) a=u->attribute->Copy();
3182    jjSTD_1_ID(res,(ideal)u->CopyD(),r,(ideal)v->CopyD(),a);
3183  }
3184  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
3185  return FALSE;
3186}
3187static BOOLEAN jjVARSTR2(leftv res, leftv u, leftv v)
3188{
3189  idhdl h=(idhdl)u->data;
3190  int i=(int)(long)v->Data();
3191  if ((0<i) && (i<=IDRING(h)->N))
3192    res->data=omStrDup(IDRING(h)->names[i-1]);
3193  else
3194  {
3195    Werror("var number %d out of range 1..%d",i,IDRING(h)->N);
3196    return TRUE;
3197  }
3198  return FALSE;
3199}
3200static BOOLEAN jjWAIT1ST2(leftv res, leftv u, leftv v)
3201{
3202  lists Lforks = (lists)u->Data();
3203  int t = (int)(long)v->Data();
3204  int i = slStatusSsiL(Lforks, t*1000);
3205  if ( i < 0 ) i = 0;
3206  res->data = (void*)(long)i;
3207  return FALSE;
3208}
3209static BOOLEAN jjWAITALL2(leftv res, leftv u, leftv v)
3210{
3211/* returns 1 iff all forks are finished; 0 otherwise */
3212  lists Lforks = (lists)u->Data();
3213  int timeout = 1000*(int)(long)v->Data();
3214  lists oneFork=(lists)omAllocBin(slists_bin);
3215  oneFork->Init(1);
3216  int i;
3217  int t = getTimer();
3218  int ret = 1;
3219  for (int j = 0; j <= Lforks->nr; j++)
3220  {
3221    oneFork->m[0].Copy(&Lforks->m[j]);
3222    i = slStatusSsiL(oneFork, timeout);
3223    if (i == 1)
3224    {
3225      timeout = timeout - getTimer() + t;
3226    }
3227    else { ret = 0; j = Lforks->nr+1; /* terminate the for loop */ }
3228    omFreeSize((ADDRESS)oneFork->m,sizeof(sleftv));
3229  }
3230  omFreeBin((ADDRESS)oneFork, slists_bin);
3231  res->data = (void*)(long)ret;
3232  return FALSE;
3233}
3234static BOOLEAN jjWEDGE(leftv res, leftv u, leftv v)
3235{
3236  res->data = (char *)mpWedge((matrix)u->Data(),(int)(long)v->Data());
3237  return FALSE;
3238}
3239#define jjWRONG2 (proc2)jjWRONG
3240#define jjWRONG3 (proc3)jjWRONG
3241static BOOLEAN jjWRONG(leftv res, leftv u)
3242{
3243  return TRUE;
3244}
3245
3246/*=================== operations with 1 arg.: static proc =================*/
3247/* must be ordered: first operations for chars (infix ops),
3248 * then alphabetically */
3249
3250static BOOLEAN jjDUMMY(leftv res, leftv u)
3251{
3252  res->data = (char *)u->CopyD();
3253  return FALSE;
3254}
3255static BOOLEAN jjNULL(leftv res, leftv u)
3256{
3257  return FALSE;
3258}
3259//static BOOLEAN jjPLUSPLUS(leftv res, leftv u)
3260//{
3261//  res->data = (char *)((int)(long)u->Data()+1);
3262//  return FALSE;
3263//}
3264//static BOOLEAN jjMINUSMINUS(leftv res, leftv u)
3265//{
3266//  res->data = (char *)((int)(long)u->Data()-1);
3267//  return FALSE;
3268//}
3269static BOOLEAN jjPLUSPLUS(leftv res, leftv u)
3270{
3271  if (IDTYP((idhdl)u->data)==INT_CMD)
3272  {
3273    int i=IDINT((idhdl)u->data);
3274    if (iiOp==PLUSPLUS) i++;
3275    else                i--;
3276    IDDATA((idhdl)u->data)=(char *)(long)i;
3277    return FALSE;
3278  }
3279  return TRUE;
3280}
3281static BOOLEAN jjUMINUS_BI(leftv res, leftv u)
3282{
3283  number n=(number)u->CopyD(BIGINT_CMD);
3284  n=nlNeg(n);
3285  res->data = (char *)n;
3286  return FALSE;
3287}
3288static BOOLEAN jjUMINUS_I(leftv res, leftv u)
3289{
3290  res->data = (char *)(-(long)u->Data());
3291  return FALSE;
3292}
3293static BOOLEAN jjUMINUS_N(leftv res, leftv u)
3294{
3295  number n=(number)u->CopyD(NUMBER_CMD);
3296  n=nNeg(n);
3297  res->data = (char *)n;
3298  return FALSE;
3299}
3300static BOOLEAN jjUMINUS_P(leftv res, leftv u)
3301{
3302  res->data = (char *)pNeg((poly)u->CopyD(POLY_CMD));
3303  return FALSE;
3304}
3305static BOOLEAN jjUMINUS_MA(leftv res, leftv u)
3306{
3307  poly m1=pISet(-1);
3308  res->data = (char *)mpMultP((matrix)u->CopyD(MATRIX_CMD),m1);
3309  return FALSE;
3310}
3311static BOOLEAN jjUMINUS_IV(leftv res, leftv u)
3312{
3313  intvec *iv=(intvec *)u->CopyD(INTVEC_CMD);
3314  (*iv)*=(-1);
3315  res->data = (char *)iv;
3316  return FALSE;
3317}
3318static BOOLEAN jjPROC1(leftv res, leftv u)
3319{
3320  return jjPROC(res,u,NULL);
3321}
3322static BOOLEAN jjBAREISS(leftv res, leftv v)
3323{
3324  //matrix m=(matrix)v->Data();
3325  //lists l=mpBareiss(m,FALSE);
3326  intvec *iv;
3327  ideal m;
3328  smCallBareiss((ideal)v->Data(),0,0,m,&iv);
3329  lists l=(lists)omAllocBin(slists_bin);
3330  l->Init(2);
3331  l->m[0].rtyp=MODUL_CMD;
3332  l->m[1].rtyp=INTVEC_CMD;
3333  l->m[0].data=(void *)m;
3334  l->m[1].data=(void *)iv;
3335  res->data = (char *)l;
3336  return FALSE;
3337}
3338//static BOOLEAN jjBAREISS_IM(leftv res, leftv v)
3339//{
3340//  intvec *m=(intvec *)v->CopyD(INTMAT_CMD);
3341//  ivTriangMat(m);
3342//  res->data = (char *)m;
3343//  return FALSE;
3344//}
3345static BOOLEAN jjBI2N(leftv res, leftv u)
3346{
3347  if (rField_is_Q())
3348  {
3349    res->data=u->CopyD();
3350    return FALSE;
3351  }
3352  else
3353  {
3354    BOOLEAN bo=FALSE;
3355    number n=(number)u->CopyD();
3356    if (rField_is_Zp())
3357    {
3358      res->data=(void *)npMap0(n);
3359    }
3360    else if (rField_is_Q_a())
3361    {
3362      res->data=(void *)naMap00(n);
3363    }
3364    else if (rField_is_Zp_a())
3365    {
3366      res->data=(void *)naMap0P(n);
3367    }
3368#ifdef HAVE_RINGS
3369    else if (rField_is_Ring_Z())
3370    {
3371      res->data=(void *)nrzMapQ(n);
3372    }
3373    else if (rField_is_Ring_ModN())
3374    {
3375      res->data=(void *)nrnMapQ(n);
3376    }
3377    else if (rField_is_Ring_PtoM())
3378    {
3379      res->data=(void *)nrnMapQ(n);
3380    }
3381    else if (rField_is_Ring_2toM())
3382    {
3383      res->data=(void *)nr2mMapQ(n);
3384    }
3385#endif
3386    else
3387    {
3388      WerrorS("cannot convert bigint to this field");
3389      bo=TRUE;
3390    }
3391    nlDelete(&n,NULL);
3392    return bo;
3393  }
3394}
3395static BOOLEAN jjBI2P(leftv res, leftv u)
3396{
3397  sleftv tmp;
3398  BOOLEAN bo=jjBI2N(&tmp,u);
3399  if (!bo)
3400  {
3401    number n=(number) tmp.data;
3402    if (nIsZero(n)) { res->data=NULL;nDelete(&n); }
3403    else
3404    {
3405      res->data=(void *)pNSet(n);
3406    }
3407  }
3408  return bo;
3409}
3410static BOOLEAN jjCALL1MANY(leftv res, leftv u)
3411{
3412  return iiExprArithM(res,u,iiOp);
3413}
3414static BOOLEAN jjCHAR(leftv res, leftv v)
3415{
3416  res->data = (char *)(long)rChar((ring)v->Data());
3417  return FALSE;
3418}
3419static BOOLEAN jjCOLS(leftv res, leftv v)
3420{
3421  res->data = (char *)(long)MATCOLS((matrix)(v->Data()));
3422  return FALSE;
3423}
3424static BOOLEAN jjCOLS_IV(leftv res, leftv v)
3425{
3426  res->data = (char *)(long)((intvec*)(v->Data()))->cols();
3427  return FALSE;
3428}
3429static BOOLEAN jjCONTENT(leftv res, leftv v)
3430{
3431  // CopyD for POLY_CMD and VECTOR_CMD are identical:
3432  poly p=(poly)v->CopyD(POLY_CMD);
3433  if (p!=NULL) p_Cleardenom(p, currRing);
3434  res->data = (char *)p;
3435  return FALSE;
3436}
3437static BOOLEAN jjCOUNT_BI(leftv res, leftv v)
3438{
3439  res->data = (char *)(long)nlSize((number)v->Data());
3440  return FALSE;
3441}
3442static BOOLEAN jjCOUNT_N(leftv res, leftv v)
3443{
3444  res->data = (char *)(long)nSize((number)v->Data());
3445  return FALSE;
3446}
3447static BOOLEAN jjCOUNT_L(leftv res, leftv v)
3448{
3449  lists l=(lists)v->Data();
3450  res->data = (char *)(long)(l->nr+1);
3451  return FALSE;
3452}
3453static BOOLEAN jjCOUNT_M(leftv res, leftv v)
3454{
3455  matrix m=(matrix)v->Data();
3456  res->data = (char *)(long)(MATROWS(m)*MATCOLS(m));
3457  return FALSE;
3458}
3459static BOOLEAN jjCOUNT_IV(leftv res, leftv v)
3460{
3461  res->data = (char *)(long)((intvec*)(v->Data()))->length();
3462  return FALSE;
3463}
3464static BOOLEAN jjCOUNT_RG(leftv res, leftv v)
3465{
3466  ring r=(ring)v->Data();
3467  int elems=-1;
3468  if (rField_is_Zp(r)||rField_is_GF(r)) elems=rInternalChar(r);
3469  else if (rField_is_Zp_a(r) && (r->minpoly!=NULL))
3470  {
3471#ifdef HAVE_FACTORY
3472    extern int ipower ( int b, int n ); /* factory/cf_util */
3473    elems=ipower(ABS(rInternalChar(r)),naParDeg(r->minpoly));
3474#else
3475    elems=(int)pow(ABS((double) rInternalChar(r)),(double)naParDeg(r->minpoly));
3476#endif
3477  }
3478  res->data = (char *)(long)elems;
3479  return FALSE;
3480}
3481static BOOLEAN jjDEG(leftv res, leftv v)
3482{
3483  int dummy;
3484  poly p=(poly)v->Data();
3485  if (p!=NULL) res->data = (char *)pLDeg(p,&dummy,currRing);
3486  else res->data=(char *)-1;
3487  return FALSE;
3488}
3489static BOOLEAN jjDEG_M(leftv res, leftv u)
3490{
3491  ideal I=(ideal)u->Data();
3492  int d=-1;
3493  int dummy;
3494  int i;
3495  for(i=IDELEMS(I)-1;i>=0;i--)
3496    if (I->m[i]!=NULL) d=si_max(d,(int)pLDeg(I->m[i],&dummy,currRing));
3497  res->data = (char *)(long)d;
3498  return FALSE;
3499}
3500static BOOLEAN jjDEGREE(leftv res, leftv v)
3501{
3502  assumeStdFlag(v);
3503  intvec *module_w=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
3504  scDegree((ideal)v->Data(),module_w,currQuotient);
3505  return FALSE;
3506}
3507static BOOLEAN jjDEFINED(leftv res, leftv v)
3508{
3509  if ((v->rtyp==IDHDL)
3510  && ((myynest==IDLEV((idhdl)v->data))||(0==IDLEV((idhdl)v->data))))
3511  {
3512    res->data=(void *)(long)(IDLEV((idhdl)v->data)+1);
3513  }
3514  else if (v->rtyp!=0) res->data=(void *)(-1);
3515  return FALSE;
3516}
3517#ifdef HAVE_FACTORY
3518static BOOLEAN jjDET(leftv res, leftv v)
3519{
3520  matrix m=(matrix)v->Data();
3521  poly p;
3522  if (smCheckDet((ideal)m,m->cols(),TRUE))
3523  {
3524    ideal I=idMatrix2Module(mpCopy(m));
3525    p=smCallDet(I);
3526    idDelete(&I);
3527  }
3528  else
3529    p=singclap_det(m);
3530  res ->data = (char *)p;
3531  return FALSE;
3532}
3533static BOOLEAN jjDET_I(leftv res, leftv v)
3534{
3535  intvec * m=(intvec*)v->Data();
3536  int i,j;
3537  i=m->rows();j=m->cols();
3538  if(i==j)
3539    res->data = (char *)(long)singclap_det_i(m);
3540  else
3541  {
3542    Werror("det of %d x %d intmat",i,j);
3543    return TRUE;
3544  }
3545  return FALSE;
3546}
3547static BOOLEAN jjDET_S(leftv res, leftv v)
3548{
3549  ideal I=(ideal)v->Data();
3550  poly p;
3551  if (IDELEMS(I)<1) return TRUE;
3552  if (smCheckDet(I,IDELEMS(I),FALSE))
3553  {
3554    matrix m=idModule2Matrix(idCopy(I));
3555    p=singclap_det(m);
3556    idDelete((ideal *)&m);
3557  }
3558  else
3559    p=smCallDet(I);
3560  res->data = (char *)p;
3561  return FALSE;
3562}
3563#endif
3564static BOOLEAN jjDIM(leftv res, leftv v)
3565{
3566  assumeStdFlag(v);
3567  res->data = (char *)(long)scDimInt((ideal)(v->Data()),currQuotient);
3568  return FALSE;
3569}
3570static BOOLEAN jjDUMP(leftv res, leftv v)
3571{
3572  si_link l = (si_link)v->Data();
3573  if (slDump(l))
3574  {
3575    const char *s;
3576    if ((l!=NULL)&&(l->name!=NULL)) s=l->name;
3577    else                            s=sNoName;
3578    Werror("cannot dump to `%s`",s);
3579    return TRUE;
3580  }
3581  else
3582    return FALSE;
3583}
3584static BOOLEAN jjE(leftv res, leftv v)
3585{
3586  res->data = (char *)pOne();
3587  int co=(int)(long)v->Data();
3588  if (co>0)
3589  {
3590    pSetComp((poly)res->data,co);
3591    pSetm((poly)res->data);
3592  }
3593  else WerrorS("argument of gen must be positive");
3594  return (co<=0);
3595}
3596static BOOLEAN jjEXECUTE(leftv res, leftv v)
3597{
3598  char * d = (char *)v->Data();
3599  char * s = (char *)omAlloc(strlen(d) + 13);
3600  strcpy( s, (char *)d);
3601  strcat( s, "\n;RETURN();\n");
3602  newBuffer(s,BT_execute);
3603  return yyparse();
3604}
3605#ifdef HAVE_FACTORY
3606static BOOLEAN jjFACSTD(leftv res, leftv v)
3607{
3608  ideal_list p,h;
3609  h=kStdfac((ideal)v->Data(),NULL,testHomog,NULL);
3610  lists L=(lists)omAllocBin(slists_bin);
3611  if (h==NULL)
3612  {
3613    L->Init(1);
3614    L->m[0].data=(char *)idInit(0,1);
3615    L->m[0].rtyp=IDEAL_CMD;
3616  }
3617  else
3618  {
3619    p=h;
3620    int l=0;
3621    while (p!=NULL) { p=p->next;l++; }
3622    L->Init(l);
3623    l=0;
3624    while(h!=NULL)
3625    {
3626      L->m[l].data=(char *)h->d;
3627      L->m[l].rtyp=IDEAL_CMD;
3628      p=h->next;
3629      omFreeSize(h,sizeof(*h));
3630      h=p;
3631      l++;
3632    }
3633  }
3634  res->data=(void *)L;
3635  return FALSE;
3636}
3637static BOOLEAN jjFAC_P(leftv res, leftv u)
3638{
3639  intvec *v=NULL;
3640  singclap_factorize_retry=0;
3641  ideal f=singclap_factorize((poly)(u->CopyD()), &v, 0);
3642  if (f==NULL) return TRUE;
3643  ivTest(v);
3644  lists l=(lists)omAllocBin(slists_bin);
3645  l->Init(2);
3646  l->m[0].rtyp=IDEAL_CMD;
3647  l->m[0].data=(void *)f;
3648  l->m[1].rtyp=INTVEC_CMD;
3649  l->m[1].data=(void *)v;
3650  res->data=(void *)l;
3651  return FALSE;
3652}
3653#endif
3654static BOOLEAN jjGETDUMP(leftv res, leftv v)
3655{
3656  si_link l = (si_link)v->Data();
3657  if (slGetDump(l))
3658  {
3659    const char *s;
3660    if ((l!=NULL)&&(l->name!=NULL)) s=l->name;
3661    else                            s=sNoName;
3662    Werror("cannot get dump from `%s`",s);
3663    return TRUE;
3664  }
3665  else
3666    return FALSE;
3667}
3668static BOOLEAN jjHIGHCORNER(leftv res, leftv v)
3669{
3670  assumeStdFlag(v);
3671  ideal I=(ideal)v->Data();
3672  res->data=(void *)iiHighCorner(I,0);
3673  return FALSE;
3674}
3675static BOOLEAN jjHIGHCORNER_M(leftv res, leftv v)
3676{
3677  assumeStdFlag(v);
3678  intvec *w=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
3679  BOOLEAN delete_w=FALSE;
3680  ideal I=(ideal)v->Data();
3681  int i;
3682  poly p=NULL,po=NULL;
3683  int rk=idRankFreeModule(I);
3684  if (w==NULL)
3685  {
3686    w = new intvec(rk);
3687    delete_w=TRUE;
3688  }
3689  for(i=rk;i>0;i--)
3690  {
3691    p=iiHighCorner(I,i);
3692    if (p==NULL)
3693    {
3694      WerrorS("module must be zero-dimensional");
3695      if (delete_w) delete w;
3696      return TRUE;
3697    }
3698    if (po==NULL)
3699    {
3700      po=p;
3701    }
3702    else
3703    {
3704      // now po!=NULL, p!=NULL
3705      int d=(pFDeg(po,currRing)-(*w)[pGetComp(po)-1] - pFDeg(p,currRing)+(*w)[i-1]);
3706      if (d==0)
3707        d=pLmCmp(po,p);
3708      if (d > 0)
3709      {
3710        pDelete(&p);
3711      }
3712      else // (d < 0)
3713      {
3714        pDelete(&po); po=p;
3715      }
3716    }
3717  }
3718  if (delete_w) delete w;
3719  res->data=(void *)po;
3720  return FALSE;
3721}
3722static BOOLEAN jjHILBERT(leftv res, leftv v)
3723{
3724  assumeStdFlag(v);
3725  intvec *module_w=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
3726  //scHilbertPoly((ideal)v->Data(),currQuotient);
3727  hLookSeries((ideal)v->Data(),module_w,currQuotient);
3728  return FALSE;
3729}
3730static BOOLEAN jjHILBERT_IV(leftv res, leftv v)
3731{
3732  res->data=(void *)hSecondSeries((intvec *)v->Data());
3733  return FALSE;
3734}
3735static BOOLEAN jjHOMOG1(leftv res, leftv v)
3736{
3737  intvec *w=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
3738  ideal v_id=(ideal)v->Data();
3739  if (w==NULL)
3740  {
3741    res->data=(void *)(long)idHomModule(v_id,currQuotient,&w);
3742    if (res->data!=NULL)
3743    {
3744      if (v->rtyp==IDHDL)
3745      {
3746        char *s_isHomog=omStrDup("isHomog");
3747        if (v->e==NULL)
3748          atSet((idhdl)(v->data),s_isHomog,w,INTVEC_CMD);
3749        else
3750          atSet((idhdl)(v->LData()),s_isHomog,w,INTVEC_CMD);
3751      }
3752      else if (w!=NULL) delete w;
3753    } // if res->data==NULL then w==NULL
3754  }
3755  else
3756  {
3757    res->data=(void *)(long)idTestHomModule(v_id,currQuotient,w);
3758    if((res->data==NULL) && (v->rtyp==IDHDL))
3759    {
3760      if (v->e==NULL)
3761        atKill((idhdl)(v->data),"isHomog");
3762      else
3763        atKill((idhdl)(v->LData()),"isHomog");
3764    }
3765  }
3766  return FALSE;
3767}
3768static BOOLEAN jjIDEAL_Ma(leftv res, leftv v)
3769{
3770  matrix mat=(matrix)v->CopyD(MATRIX_CMD);
3771  IDELEMS((ideal)mat)=MATCOLS(mat)*MATROWS(mat);
3772  if (IDELEMS((ideal)mat)==0)
3773  {
3774    idDelete((ideal *)&mat);
3775    mat=(matrix)idInit(1,1);
3776  }
3777  else
3778  {
3779    MATROWS(mat)=1;
3780    mat->rank=1;
3781    idTest((ideal)mat);
3782  }
3783  res->data=(char *)mat;
3784  return FALSE;
3785}
3786static BOOLEAN jjIDEAL_Map(leftv res, leftv v)
3787{
3788  map m=(map)v->CopyD(MAP_CMD);
3789  omFree((ADDRESS)m->preimage);
3790  m->preimage=NULL;
3791  ideal I=(ideal)m;
3792  I->rank=1;
3793  res->data=(char *)I;
3794  return FALSE;
3795}
3796static BOOLEAN jjIDEAL_R(leftv res, leftv v)
3797{
3798  if (currRing!=NULL)
3799  {
3800    ring q=(ring)v->Data();
3801    if (rSamePolyRep(currRing, q))
3802    {
3803      if (q->qideal==NULL)
3804        res->data=(char *)idInit(1,1);
3805      else
3806        res->data=(char *)idCopy(q->qideal);
3807      return FALSE;
3808    }
3809  }
3810  WerrorS("can only get ideal from identical qring");
3811  return TRUE;
3812}
3813static BOOLEAN jjIm2Iv(leftv res, leftv v)
3814{
3815  intvec *iv = (intvec *)v->CopyD(INTMAT_CMD);
3816  iv->makeVector();
3817  res->data = iv;
3818  return FALSE;
3819}
3820static BOOLEAN jjIMPART(leftv res, leftv v)
3821{
3822  res->data = (char *)nImPart((number)v->Data());
3823  return FALSE;
3824}
3825static BOOLEAN jjINDEPSET(leftv res, leftv v)
3826{
3827  assumeStdFlag(v);
3828  res->data=(void *)scIndIntvec((ideal)(v->Data()),currQuotient);
3829  return FALSE;
3830}
3831static BOOLEAN jjINTERRED(leftv res, leftv v)
3832{
3833  ideal result=kInterRed((ideal)(v->Data()), currQuotient);
3834  if (TEST_OPT_PROT) { PrintLn(); mflush(); }
3835  res->data = result;
3836  return FALSE;
3837}
3838static BOOLEAN jjIS_RINGVAR_P(leftv res, leftv v)
3839{
3840  res->data = (char *)(long)pVar((poly)v->Data());
3841  return FALSE;
3842}
3843static BOOLEAN jjIS_RINGVAR_S(leftv res, leftv v)
3844{
3845  res->data = (char *)(long)(r_IsRingVar((char *)v->Data(), currRing)+1);
3846  return FALSE;
3847}
3848static BOOLEAN jjIS_RINGVAR0(leftv res, leftv v)
3849{
3850  res->data = (char *)0;
3851  return FALSE;
3852}
3853static BOOLEAN jjJACOB_P(leftv res, leftv v)
3854{
3855  ideal i=idInit(pVariables,1);
3856  int k;
3857  poly p=(poly)(v->Data());
3858  for (k=pVariables;k>0;k--)
3859  {
3860    i->m[k-1]=pDiff(p,k);
3861  }
3862  res->data = (char *)i;
3863  return FALSE;
3864}
3865/*2
3866 * compute Jacobi matrix of a module/matrix
3867 * Jacobi(M) := ( diff(Mt,var(1))|, ... ,| diff(Mt,var(pVariables))  ),
3868 * where Mt := transpose(M)
3869 * Note that this is consistent with the current conventions for jacob in Singular,
3870 * whereas M2 computes its transposed.
3871 */
3872static BOOLEAN jjJACOB_M(leftv res, leftv a)
3873{
3874  ideal id = (ideal)a->Data();
3875  id = idTransp(id);
3876  int W = IDELEMS(id);
3877
3878  ideal result = idInit(W * pVariables, id->rank);
3879  poly *p = result->m;
3880
3881  for( int v = 1; v <= pVariables; v++ )
3882  {
3883    poly* q = id->m;
3884    for( int i = 0; i < W; i++, p++, q++ )
3885      *p = pDiff( *q, v );
3886  }
3887  idDelete(&id);
3888
3889  res->data = (char *)result;
3890  return FALSE;
3891}
3892
3893
3894static BOOLEAN jjKBASE(leftv res, leftv v)
3895{
3896  assumeStdFlag(v);
3897  res->data = (char *)scKBase(-1,(ideal)(v->Data()),currQuotient);
3898  return FALSE;
3899}
3900#ifdef MDEBUG
3901static BOOLEAN jjpHead(leftv res, leftv v)
3902{
3903  res->data=(char *)pHead((poly)v->Data());
3904  return FALSE;
3905}
3906#endif
3907static BOOLEAN jjL2R(leftv res, leftv v)
3908{
3909  res->data=(char *)syConvList((lists)v->Data());
3910  if (res->data != NULL)
3911    return FALSE;
3912  else
3913    return TRUE;
3914}
3915static BOOLEAN jjLEADCOEF(leftv res, leftv v)
3916{
3917  poly p=(poly)v->Data();
3918  if (p==NULL)
3919  {
3920    res->data=(char *)nInit(0);
3921  }
3922  else
3923  {
3924    res->data=(char *)nCopy(pGetCoeff(p));
3925  }
3926  return FALSE;
3927}
3928static BOOLEAN jjLEADEXP(leftv res, leftv v)
3929{
3930  poly p=(poly)v->Data();
3931  int s=pVariables;
3932  if (v->Typ()==VECTOR_CMD) s++;
3933  intvec *iv=new intvec(s);
3934  if (p!=NULL)
3935  {
3936    for(int i = pVariables;i;i--)
3937    {
3938      (*iv)[i-1]=pGetExp(p,i);
3939    }
3940    if (s!=pVariables)
3941      (*iv)[pVariables]=pGetComp(p);
3942  }
3943  res->data=(char *)iv;
3944  return FALSE;
3945}
3946static BOOLEAN jjLEADMONOM(leftv res, leftv v)
3947{
3948  poly p=(poly)v->Data();
3949  if (p == NULL)
3950  {
3951    res->data = (char*) NULL;
3952  }
3953  else
3954  {
3955    poly lm = pLmInit(p);
3956    pSetCoeff(lm, nInit(1));
3957    res->data = (char*) lm;
3958  }
3959  return FALSE;
3960}
3961static BOOLEAN jjLOAD1(leftv res, leftv v)
3962{
3963  return jjLOAD(res, v,FALSE);
3964}
3965static BOOLEAN jjLISTRING(leftv res, leftv v)
3966{
3967  ring r=rCompose((lists)v->Data());
3968  if (r==NULL) return TRUE;
3969  if (r->qideal!=NULL) res->rtyp=QRING_CMD;
3970  res->data=(char *)r;
3971  return FALSE;
3972}
3973#if SIZEOF_LONG == 8
3974static number jjLONG2N(long d)
3975{
3976  int i=(int)d;
3977  if ((long)i == d)
3978  {
3979    return nlInit(i, NULL);
3980  }
3981  else
3982  {
3983#if !defined(OM_NDEBUG) && !defined(NDEBUG)
3984    omCheckBin(rnumber_bin);
3985#endif
3986    number z=(number)omAllocBin(rnumber_bin);
3987    #if defined(LDEBUG)
3988    z->debug=123456;
3989    #endif
3990    z->s=3;
3991    mpz_init_set_si(z->z,d);
3992    return z;
3993  }
3994}
3995#else
3996#define jjLONG2N(D) nlInit((int)D, NULL)
3997#endif
3998static BOOLEAN jjPFAC1(leftv res, leftv v)
3999{
4000  /* call method jjPFAC2 with second argument = 0 (meaning that no
4001     valid bound for the prime factors has been given) */
4002  sleftv tmp;
4003  memset(&tmp, 0, sizeof(tmp));
4004  tmp.rtyp = INT_CMD;
4005  return jjPFAC2(res, v, &tmp);
4006}
4007static BOOLEAN jjLU_DECOMP(leftv res, leftv v)
4008{
4009  /* computes the LU-decomposition of a matrix M;
4010     i.e., M = P * L * U, where
4011        - P is a row permutation matrix,
4012        - L is in lower triangular form,
4013        - U is in upper row echelon form
4014     Then, we also have P * M = L * U.
4015     A list [P, L, U] is returned. */
4016  matrix mat = (const matrix)v->Data();
4017  int rr = mat->rows();
4018  int cc = mat->cols();
4019  matrix pMat;
4020  matrix lMat;
4021  matrix uMat;
4022
4023  luDecomp(mat, pMat, lMat, uMat);
4024
4025  lists ll = (lists)omAllocBin(slists_bin);
4026  ll->Init(3);
4027  ll->m[0].rtyp=MATRIX_CMD; ll->m[0].data=(void *)pMat;
4028  ll->m[1].rtyp=MATRIX_CMD; ll->m[1].data=(void *)lMat;
4029  ll->m[2].rtyp=MATRIX_CMD; ll->m[2].data=(void *)uMat;
4030  res->data=(char*)ll;
4031
4032  return FALSE;
4033}
4034static BOOLEAN jjMEMORY(leftv res, leftv v)
4035{
4036  omUpdateInfo();
4037  long d;
4038  switch(((int)(long)v->Data()))
4039  {
4040  case 0:
4041    res->data=(char *)jjLONG2N(om_Info.UsedBytes);
4042    break;
4043  case 1:
4044    res->data = (char *)jjLONG2N(om_Info.CurrentBytesSystem);
4045    break;
4046  case 2:
4047    res->data = (char *)jjLONG2N(om_Info.MaxBytesSystem);
4048    break;
4049  default:
4050    omPrintStats(stdout);
4051    omPrintInfo(stdout);
4052    omPrintBinStats(stdout);
4053    res->data = (char *)0;
4054    res->rtyp = NONE;
4055  }
4056  return FALSE;
4057  res->data = (char *)0;
4058  return FALSE;
4059}
4060//static BOOLEAN jjMONITOR1(leftv res, leftv v)
4061//{
4062//  return jjMONITOR2(res,v,NULL);
4063//}
4064static BOOLEAN jjMSTD(leftv res, leftv v)
4065{
4066  int t=v->Typ();
4067  ideal r,m;
4068  r=kMin_std((ideal)v->Data(),currQuotient,testHomog,NULL,m);
4069  lists l=(lists)omAllocBin(slists_bin);
4070  l->Init(2);
4071  l->m[0].rtyp=t;
4072  l->m[0].data=(char *)r;
4073  setFlag(&(l->m[0]),FLAG_STD);
4074  l->m[1].rtyp=t;
4075  l->m[1].data=(char *)m;
4076  res->data=(char *)l;
4077  return FALSE;
4078}
4079static BOOLEAN jjMULT(leftv res, leftv v)
4080{
4081  assumeStdFlag(v);
4082  res->data = (char *)(long)scMultInt((ideal)(v->Data()),currQuotient);
4083  return FALSE;
4084}
4085static BOOLEAN jjMINRES_R(leftv res, leftv v)
4086{
4087  intvec *weights=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
4088  res->data=(char *)syMinimize((syStrategy)v->Data());
4089  if (weights!=NULL)
4090    atSet(res, omStrDup("isHomog"),ivCopy(weights),INTVEC_CMD);
4091  return FALSE;
4092}
4093static BOOLEAN jjN2BI(leftv res, leftv v)
4094{
4095  number n,i; i=(number)v->Data();
4096  if (rField_is_Zp())
4097  {
4098    n=nlInit(npInt(i,currRing),NULL);
4099  }
4100  else if (rField_is_Q()) n=nlBigInt(i);
4101#ifdef HAVE_RINGS
4102  else if (rField_is_Ring_Z() || rField_is_Ring_ModN() || rField_is_Ring_PtoM()) n=nlMapGMP(i);
4103  else if (rField_is_Ring_2toM()) n=nlInit((unsigned long) i,NULL);
4104#endif
4105  else goto err;
4106  res->data=(void *)n;
4107  return FALSE;
4108err:
4109  WerrorS("cannot convert to bigint"); return TRUE;
4110}
4111static BOOLEAN jjNAMEOF(leftv res, leftv v)
4112{
4113  res->data = (char *)v->name;
4114  if (res->data==NULL) res->data=omStrDup("");
4115  v->name=NULL;
4116  return FALSE;
4117}
4118static BOOLEAN jjNAMES(leftv res, leftv v)
4119{
4120  res->data=ipNameList(((ring)v->Data())->idroot);
4121  return FALSE;
4122}
4123static BOOLEAN jjNVARS(leftv res, leftv v)
4124{
4125  res->data = (char *)(long)(((ring)(v->Data()))->N);
4126  return FALSE;
4127}
4128static BOOLEAN jjOpenClose(leftv res, leftv v)
4129{
4130  si_link l=(si_link)v->Data();
4131  if (iiOp==OPEN_CMD) return slOpen(l, SI_LINK_OPEN,v);
4132  else                return slClose(l);
4133}
4134static BOOLEAN jjORD(leftv res, leftv v)
4135{
4136  poly p=(poly)v->Data();
4137  res->data=(char *)( p==NULL ? -1 : pFDeg(p,currRing) );
4138  return FALSE;
4139}
4140static BOOLEAN jjPAR1(leftv res, leftv v)
4141{
4142  int i=(int)(long)v->Data();
4143  int p=0;
4144  p=rPar(currRing);
4145  if ((0<i) && (i<=p))
4146  {
4147    res->data=(char *)nPar(i);
4148  }
4149  else
4150  {
4151    Werror("par number %d out of range 1..%d",i,p);
4152    return TRUE;
4153  }
4154  return FALSE;
4155}
4156static BOOLEAN jjPARDEG(leftv res, leftv v)
4157{
4158  res->data = (char *)(long)nParDeg((number)v->Data());
4159  return FALSE;
4160}
4161static BOOLEAN jjPARSTR1(leftv res, leftv v)
4162{
4163  if (currRing==NULL)
4164  {
4165    WerrorS("no ring active");
4166    return TRUE;
4167  }
4168  int i=(int)(long)v->Data();
4169  int p=0;
4170  if ((0<i) && (currRing->parameter!=NULL) && (i<=(p=rPar(currRing))))
4171    res->data=omStrDup(currRing->parameter[i-1]);
4172  else
4173  {
4174    Werror("par number %d out of range 1..%d",i,p);
4175    return TRUE;
4176  }
4177  return FALSE;
4178}
4179static BOOLEAN jjP2BI(leftv res, leftv v)
4180{
4181  poly p=(poly)v->Data();
4182  if (p==NULL) { res->data=(char *)nlInit(0,NULL); return FALSE; }
4183  if ((pNext(p)!=NULL)|| (!pIsConstant(p)))
4184  {
4185    WerrorS("poly must be constant");
4186    return TRUE;
4187  }
4188  number i=pGetCoeff(p);
4189  number n;
4190  if (rField_is_Zp())
4191  {
4192    n=nlInit(npInt(i,currRing), NULL);
4193  }
4194  else if (rField_is_Q()) n=nlBigInt(i);
4195#ifdef HAVE_RINGS
4196  else if (rField_is_Ring_Z() || rField_is_Ring_ModN() || rField_is_Ring_PtoM())
4197    n=nlMapGMP(i);
4198  else if (rField_is_Ring_2toM())
4199    n=nlInit((unsigned long) i, NULL);
4200#endif
4201  else goto err;
4202  res->data=(void *)n;
4203  return FALSE;
4204err:
4205  WerrorS("cannot convert to bigint"); return TRUE;
4206}
4207static BOOLEAN jjP2I(leftv res, leftv v)
4208{
4209  poly p=(poly)v->Data();
4210  if (p==NULL) { /*res->data=(char *)0;*/ return FALSE; }
4211  if ((pNext(p)!=NULL)|| (!pIsConstant(p)))
4212  {
4213    WerrorS("poly must be constant");
4214    return TRUE;
4215  }
4216  res->data = (char *)(long)n_Int(pGetCoeff(p),currRing);
4217  return FALSE;
4218}
4219static BOOLEAN jjPREIMAGE_R(leftv res, leftv v)
4220{
4221  map mapping=(map)v->Data();
4222  syMake(res,omStrDup(mapping->preimage));
4223  return FALSE;
4224}
4225static BOOLEAN jjPRIME(leftv res, leftv v)
4226{
4227  int i = IsPrime((int)(long)(v->Data()));
4228  res->data = (char *)(long)(i > 1 ? i : 2);
4229  return FALSE;
4230}
4231static BOOLEAN jjPRUNE(leftv res, leftv v)
4232{
4233  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
4234  ideal v_id=(ideal)v->Data();
4235  if (w!=NULL)
4236  {
4237    if (!idTestHomModule(v_id,currQuotient,w))
4238    {
4239      WarnS("wrong weights");
4240      w=NULL;
4241      // and continue at the non-homog case below
4242    }
4243    else
4244    {
4245      w=ivCopy(w);
4246      intvec **ww=&w;
4247      res->data = (char *)idMinEmbedding(v_id,FALSE,ww);
4248      atSet(res,omStrDup("isHomog"),*ww,INTVEC_CMD);
4249      return FALSE;
4250    }
4251  }
4252  res->data = (char *)idMinEmbedding(v_id);
4253  return FALSE;
4254}
4255static BOOLEAN jjP2N(leftv res, leftv v)
4256{
4257  number n;
4258  poly p;
4259  if (((p=(poly)v->Data())!=NULL)
4260  && (pIsConstant(p)))
4261  {
4262    n=nCopy(pGetCoeff(p));
4263  }
4264  else
4265  {
4266    n=nInit(0);
4267  }
4268  res->data = (char *)n;
4269  return FALSE;
4270}
4271static BOOLEAN jjRESERVEDNAME(leftv res, leftv v)
4272{
4273  char *s= (char *)v->Data();
4274  int i = 1;
4275  int l = strlen(s);
4276  for(i=0; i<sArithBase.nCmdUsed; i++)
4277  {
4278    //Print("test %d, >>%s<<, tab:>>%s<<\n",i,s,sArithBase.sCmds[i].name);
4279    if (strcmp(s, sArithBase.sCmds[i].name) == 0)
4280    {
4281      res->data = (char *)1;
4282      return FALSE;
4283    }
4284  }
4285  //res->data = (char *)0;
4286  return FALSE;
4287}
4288static BOOLEAN jjRANK1(leftv res, leftv v)
4289{
4290  matrix m =(matrix)v->Data();
4291  int rank = luRank(m, 0);
4292  res->data =(char *)(long)rank;
4293  return FALSE;
4294}
4295static BOOLEAN jjREAD(leftv res, leftv v)
4296{
4297  return jjREAD2(res,v,NULL);
4298}
4299static BOOLEAN jjREGULARITY(leftv res, leftv v)
4300{
4301  res->data = (char *)(long)iiRegularity((lists)v->Data());
4302  return FALSE;
4303}
4304static BOOLEAN jjREPART(leftv res, leftv v)
4305{
4306  res->data = (char *)nRePart((number)v->Data());
4307  return FALSE;
4308}
4309static BOOLEAN jjRINGLIST(leftv res, leftv v)
4310{
4311  ring r=(ring)v->Data();
4312  if (r!=NULL)
4313    res->data = (char *)rDecompose((ring)v->Data());
4314  return (r==NULL)||(res->data==NULL);
4315}
4316static BOOLEAN jjROWS(leftv res, leftv v)
4317{
4318  ideal i = (ideal)v->Data();
4319  res->data = (char *)i->rank;
4320  return FALSE;
4321}
4322static BOOLEAN jjROWS_IV(leftv res, leftv v)
4323{
4324  res->data = (char *)(long)((intvec*)(v->Data()))->rows();
4325  return FALSE;
4326}
4327static BOOLEAN jjRPAR(leftv res, leftv v)
4328{
4329  res->data = (char *)(long)rPar(((ring)v->Data()));
4330  return FALSE;
4331}
4332static BOOLEAN jjSLIM_GB(leftv res, leftv u)
4333{
4334#ifdef HAVE_PLURAL
4335  const bool bIsSCA = rIsSCA(currRing);
4336#else
4337  const bool bIsSCA = false;
4338#endif
4339
4340  if ((currQuotient!=NULL) && !bIsSCA)
4341  {
4342    WerrorS("qring not supported by slimgb at the moment");
4343    return TRUE;
4344  }
4345  if (rHasLocalOrMixedOrdering_currRing())
4346  {
4347    WerrorS("ordering must be global for slimgb");
4348    return TRUE;
4349  }
4350  intvec *w=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
4351  tHomog hom=testHomog;
4352  ideal u_id=(ideal)u->Data();
4353  if (w!=NULL)
4354  {
4355    if (!idTestHomModule(u_id,currQuotient,w))
4356    {
4357      WarnS("wrong weights");
4358      w=NULL;
4359    }
4360    else
4361    {
4362      w=ivCopy(w);
4363      hom=isHomog;
4364    }
4365  }
4366
4367  assume(u_id->rank>=idRankFreeModule(u_id));
4368  res->data=(char *)t_rep_gb(currRing,
4369    u_id,u_id->rank);
4370  //res->data=(char *)t_rep_gb(currRing, u_id);
4371
4372  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
4373  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
4374  return FALSE;
4375}
4376static BOOLEAN jjSTD(leftv res, leftv v)
4377{
4378  ideal result;
4379  ideal v_id=(ideal)v->Data();
4380  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
4381  tHomog hom=testHomog;
4382  if (w!=NULL)
4383  {
4384    if (!idTestHomModule(v_id,currQuotient,w))
4385    {
4386      WarnS("wrong weights");
4387      w=NULL;
4388    }
4389    else
4390    {
4391      hom=isHomog;
4392      w=ivCopy(w);
4393    }
4394  }
4395  result=kStd(v_id,currQuotient,hom,&w);
4396  idSkipZeroes(result);
4397  res->data = (char *)result;
4398  if(!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
4399  if (w!=NULL) atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
4400  return FALSE;
4401}
4402static BOOLEAN jjSort_Id(leftv res, leftv v)
4403{
4404  res->data = (char *)idSort((ideal)v->Data());
4405  return FALSE;
4406}
4407#ifdef HAVE_FACTORY
4408extern int singclap_factorize_retry;
4409static BOOLEAN jjSQR_FREE(leftv res, leftv u)
4410{
4411  intvec *v=NULL;
4412  singclap_factorize_retry=0;
4413  ideal f=singclap_sqrfree((poly)(u->CopyD()));
4414  if (f==NULL)
4415    return TRUE;
4416  res->data=(void *)f;
4417  return FALSE;
4418}
4419#endif
4420#if 1
4421static BOOLEAN jjSYZYGY(leftv res, leftv v)
4422{
4423  intvec *w=NULL;
4424  res->data = (char *)idSyzygies((ideal)v->Data(),testHomog,&w);
4425  if (w!=NULL) delete w;
4426  return FALSE;
4427}
4428#else
4429// activate, if idSyz handle module weights correctly !
4430static BOOLEAN jjSYZYGY(leftv res, leftv v)
4431{
4432  intvec *w=(intvec *)atGet(v,"isHomog",INTVEC_CMD);
4433  ideal v_id=(ideal)v->Data();
4434  tHomog hom=testHomog;
4435  int add_row_shift=0;
4436  if (w!=NULL)
4437  {
4438    w=ivCopy(w);
4439    add_row_shift=w->min_in();
4440    (*w)-=add_row_shift;
4441    if (idTestHomModule(v_id,currQuotient,w))
4442      hom=isHomog;
4443    else
4444    {
4445      //WarnS("wrong weights");
4446      delete w; w=NULL;
4447      hom=testHomog;
4448    }
4449  }
4450  res->data = (char *)idSyzygies(v_id,hom,&w);
4451  if (w!=NULL)
4452  {
4453    atSet(res,omStrDup("isHomog"),w,INTVEC_CMD);
4454  }
4455  return FALSE;
4456}
4457#endif
4458static BOOLEAN jjTRACE_IV(leftv res, leftv v)
4459{
4460  res->data = (char *)(long)ivTrace((intvec*)(v->Data()));
4461  return FALSE;
4462}
4463static BOOLEAN jjTRANSP_IV(leftv res, leftv v)
4464{
4465  res->data = (char *)ivTranp((intvec*)(v->Data()));
4466  return FALSE;
4467}
4468#ifdef HAVE_PLURAL
4469static BOOLEAN jjOPPOSITE(leftv res, leftv a)
4470{
4471  ring    r = (ring)a->Data();
4472  //if (rIsPluralRing(r))
4473  if (r->OrdSgn==1)
4474  {
4475    res->data = rOpposite(r);
4476  }
4477  else
4478  {
4479    WarnS("opposite only for global orderings");
4480    res->data = rCopy(r);
4481  }
4482  return FALSE;
4483}
4484static BOOLEAN jjENVELOPE(leftv res, leftv a)
4485{
4486  ring    r = (ring)a->Data();
4487  if (rIsPluralRing(r))
4488  {
4489    //    ideal   i;
4490//     if (a->rtyp == QRING_CMD)
4491//     {
4492//       i = r->qideal;
4493//       r->qideal = NULL;
4494//     }
4495    ring s = rEnvelope(r);
4496//     if (a->rtyp == QRING_CMD)
4497//     {
4498//       ideal is  = idOppose(r,i); /* twostd? */
4499//       is        = idAdd(is,i);
4500//       s->qideal = i;
4501//     }
4502    res->data = s;
4503  }
4504  else  res->data = rCopy(r);
4505  return FALSE;
4506}
4507static BOOLEAN jjTWOSTD(leftv res, leftv a)
4508{
4509  if (rIsPluralRing(currRing))  res->data=(ideal)twostd((ideal)a->Data());
4510  else  res->data=(ideal)a->CopyD();
4511  setFlag(res,FLAG_STD);
4512  setFlag(res,FLAG_TWOSTD);
4513  return FALSE;
4514}
4515#endif
4516
4517static BOOLEAN jjTYPEOF(leftv res, leftv v)
4518{
4519  int t=(int)(long)v->data;
4520  switch (t)
4521  {
4522    case INT_CMD:        res->data=omStrDup("int"); break;
4523    case POLY_CMD:       res->data=omStrDup("poly"); break;
4524    case VECTOR_CMD:     res->data=omStrDup("vector"); break;
4525    case STRING_CMD:     res->data=omStrDup("string"); break;
4526    case INTVEC_CMD:     res->data=omStrDup("intvec"); break;
4527    case IDEAL_CMD:      res->data=omStrDup("ideal"); break;
4528    case MATRIX_CMD:     res->data=omStrDup("matrix"); break;
4529    case MODUL_CMD:      res->data=omStrDup("module"); break;
4530    case MAP_CMD:        res->data=omStrDup("map"); break;
4531    case PROC_CMD:       res->data=omStrDup("proc"); break;
4532    case RING_CMD:       res->data=omStrDup("ring"); break;
4533    case QRING_CMD:      res->data=omStrDup("qring"); break;
4534    case INTMAT_CMD:     res->data=omStrDup("intmat"); break;
4535    case NUMBER_CMD:     res->data=omStrDup("number"); break;
4536    case BIGINT_CMD:     res->data=omStrDup("bigint"); break;
4537    case LIST_CMD:       res->data=omStrDup("list"); break;
4538    case PACKAGE_CMD:    res->data=omStrDup("package"); break;
4539    case LINK_CMD:       res->data=omStrDup("link"); break;
4540    case RESOLUTION_CMD: res->data=omStrDup("resolution");break;
4541    case DEF_CMD:
4542    case NONE:           res->data=omStrDup("none"); break;
4543    default:
4544    {
4545      if (t>MAX_TOK)
4546        res->data=omStrDup(getBlackboxName(t));
4547      else
4548        res->data=omStrDup("?unknown type?");
4549      break;
4550    }
4551  }
4552  return FALSE;
4553}
4554static BOOLEAN jjUNIVARIATE(leftv res, leftv v)
4555{
4556  res->data=(char *)pIsUnivariate((poly)v->Data());
4557  return FALSE;
4558}
4559static BOOLEAN jjVAR1(leftv res, leftv v)
4560{
4561  int i=(int)(long)v->Data();
4562  if ((0<i) && (i<=currRing->N))
4563  {
4564    poly p=pOne();
4565    pSetExp(p,i,1);
4566    pSetm(p);
4567    res->data=(char *)p;
4568  }
4569  else
4570  {
4571    Werror("var number %d out of range 1..%d",i,currRing->N);
4572    return TRUE;
4573  }
4574  return FALSE;
4575}
4576static BOOLEAN jjVARSTR1(leftv res, leftv v)
4577{
4578  if (currRing==NULL)
4579  {
4580    WerrorS("no ring active");
4581    return TRUE;
4582  }
4583  int i=(int)(long)v->Data();
4584  if ((0<i) && (i<=currRing->N))
4585    res->data=omStrDup(currRing->names[i-1]);
4586  else
4587  {
4588    Werror("var number %d out of range 1..%d",i,currRing->N);
4589    return TRUE;
4590  }
4591  return FALSE;
4592}
4593static BOOLEAN jjVDIM(leftv res, leftv v)
4594{
4595  assumeStdFlag(v);
4596  res->data = (char *)(long)scMult0Int((ideal)v->Data(),currQuotient);
4597  return FALSE;
4598}
4599BOOLEAN jjWAIT1ST1(leftv res, leftv a)
4600{
4601  lists Lforks = (lists)a->Data();
4602  int i = slStatusSsiL(Lforks, -1);
4603  while (i <= 0) i = slStatusSsiL(Lforks, 10000000); /* redo this all 10 seconds */
4604  res->data = (void*)(long)i;
4605  return FALSE;
4606}
4607BOOLEAN jjWAITALL1(leftv res, leftv a)
4608{
4609  lists Lforks = (lists)a->Data();
4610  lists oneFork=(lists)omAllocBin(slists_bin);
4611  oneFork->Init(1);
4612  int i;
4613  for (int j = 0; j <= Lforks->nr; j++)
4614  {
4615    oneFork->m[0].Copy(&Lforks->m[j]);
4616    i = slStatusSsiL(oneFork, -1);
4617    while (i != 1) i = slStatusSsiL(oneFork, 10000000); /* redo this all 10 seconds */
4618    omFreeSize((ADDRESS)oneFork->m,sizeof(sleftv));
4619  }
4620  omFreeBin((ADDRESS)oneFork, slists_bin);
4621  return FALSE;
4622}
4623static BOOLEAN jjLOAD(leftv res, leftv v, BOOLEAN autoexport)
4624{
4625  char * s=(char *)v->CopyD();
4626  char libnamebuf[256];
4627  lib_types LT = type_of_LIB(s, libnamebuf);
4628#ifdef HAVE_DYNAMIC_LOADING
4629  extern BOOLEAN load_modules(char *newlib, char *fullpath, BOOLEAN autoexport);
4630#endif /* HAVE_DYNAMIC_LOADING */
4631  switch(LT)
4632  {
4633      default:
4634      case LT_NONE:
4635        Werror("%s: unknown type", s);
4636        break;
4637      case LT_NOTFOUND:
4638        Werror("cannot open %s", s);
4639        break;
4640
4641      case LT_SINGULAR:
4642      {
4643        char *plib = iiConvName(s);
4644        idhdl pl = IDROOT->get(plib,0);
4645        if (pl==NULL)
4646        {
4647          pl = enterid( plib,0, PACKAGE_CMD, &(basePack->idroot), TRUE );
4648          IDPACKAGE(pl)->language = LANG_SINGULAR;
4649          IDPACKAGE(pl)->libname=omStrDup(plib);
4650        }
4651        else if (IDTYP(pl)!=PACKAGE_CMD)
4652        {
4653          Werror("can not create package `%s`",plib);
4654          omFree(plib);
4655          return TRUE;
4656        }
4657        package savepack=currPack;
4658        currPack=IDPACKAGE(pl);
4659        IDPACKAGE(pl)->loaded=TRUE;
4660        char libnamebuf[256];
4661        FILE * fp = feFopen( s, "r", libnamebuf, TRUE );
4662        BOOLEAN bo=iiLoadLIB(fp, libnamebuf, s, pl, autoexport, TRUE);
4663        currPack=savepack;
4664        IDPACKAGE(pl)->loaded=(!bo);
4665        return bo;
4666      }
4667      case LT_MACH_O:
4668      case LT_ELF:
4669      case LT_HPUX:
4670#ifdef HAVE_DYNAMIC_LOADING
4671        return load_modules(s, libnamebuf, autoexport);
4672#else /* HAVE_DYNAMIC_LOADING */
4673        WerrorS("Dynamic modules are not supported by this version of Singular");
4674        break;
4675#endif /* HAVE_DYNAMIC_LOADING */
4676  }
4677  return TRUE;
4678}
4679
4680#ifdef INIT_BUG
4681#define XS(A) -((short)A)
4682#define jjstrlen       (proc1)1
4683#define jjpLength      (proc1)2
4684#define jjidElem       (proc1)3
4685#define jjmpDetBareiss (proc1)4
4686#define jjidFreeModule (proc1)5
4687#define jjidVec2Ideal  (proc1)6
4688#define jjrCharStr     (proc1)7
4689#ifndef MDEBUG
4690#define jjpHead        (proc1)8
4691#endif
4692#define jjidHead       (proc1)9
4693#define jjidMaxIdeal   (proc1)10
4694#define jjidMinBase    (proc1)11
4695#define jjsyMinBase    (proc1)12
4696#define jjpMaxComp     (proc1)13
4697#define jjmpTrace      (proc1)14
4698#define jjmpTransp     (proc1)15
4699#define jjrOrdStr      (proc1)16
4700#define jjrVarStr      (proc1)18
4701#define jjrParStr      (proc1)19
4702#define jjCOUNT_RES    (proc1)22
4703#define jjDIM_R        (proc1)23
4704#define jjidTransp     (proc1)24
4705
4706extern struct sValCmd1 dArith1[];
4707void jjInitTab1()
4708{
4709  int i=0;
4710  for (;dArith1[i].cmd!=0;i++)
4711  {
4712    if (dArith1[i].res<0)
4713    {
4714      switch ((int)dArith1[i].p)
4715      {
4716        case (int)jjstrlen:       dArith1[i].p=(proc1)strlen; break;
4717        case (int)jjpLength:      dArith1[i].p=(proc1)pLength; break;
4718        case (int)jjidElem:       dArith1[i].p=(proc1)idElem; break;
4719        case (int)jjidVec2Ideal:  dArith1[i].p=(proc1)idVec2Ideal; break;
4720#ifndef HAVE_FACTORY
4721        case (int)jjmpDetBareiss: dArith1[i].p=(proc1)mpDetBareiss; break;
4722#endif
4723        case (int)jjidFreeModule: dArith1[i].p=(proc1)idFreeModule; break;
4724        case (int)jjrCharStr:     dArith1[i].p=(proc1)rCharStr; break;
4725#ifndef MDEBUG
4726        case (int)jjpHead:        dArith1[i].p=(proc1)pHeadProc; break;
4727#endif
4728        case (int)jjidHead:       dArith1[i].p=(proc1)idHead; break;
4729        case (int)jjidMaxIdeal:   dArith1[i].p=(proc1)idMaxIdeal; break;
4730        case (int)jjidMinBase:    dArith1[i].p=(proc1)idMinBase; break;
4731        case (int)jjsyMinBase:    dArith1[i].p=(proc1)syMinBase; break;
4732        case (int)jjpMaxComp:     dArith1[i].p=(proc1)pMaxCompProc; break;
4733        case (int)jjmpTrace:      dArith1[i].p=(proc1)mpTrace; break;
4734        case (int)jjmpTransp:     dArith1[i].p=(proc1)mpTransp; break;
4735        case (int)jjrOrdStr:      dArith1[i].p=(proc1)rOrdStr; break;
4736        case (int)jjrVarStr:      dArith1[i].p=(proc1)rVarStr; break;
4737        case (int)jjrParStr:      dArith1[i].p=(proc1)rParStr; break;
4738        case (int)jjCOUNT_RES:    dArith1[i].p=(proc1)sySize; break;
4739        case (int)jjDIM_R:        dArith1[i].p=(proc1)syDim; break;
4740        case (int)jjidTransp:     dArith1[i].p=(proc1)idTransp; break;
4741        default: Werror("missing proc1-definition for %d",(int)(long)dArith1[i].p);
4742      }
4743    }
4744  }
4745}
4746#else
4747#if defined(PROC_BUG)
4748#define XS(A) A
4749static BOOLEAN jjstrlen(leftv res, leftv v)
4750{
4751  res->data = (char *)strlen((char *)v->Data());
4752  return FALSE;
4753}
4754static BOOLEAN jjpLength(leftv res, leftv v)
4755{
4756  res->data = (char *)pLength((poly)v->Data());
4757  return FALSE;
4758}
4759static BOOLEAN jjidElem(leftv res, leftv v)
4760{
4761  res->data = (char *)idElem((ideal)v->Data());
4762  return FALSE;
4763}
4764static BOOLEAN jjmpDetBareiss(leftv res, leftv v)
4765{
4766  res->data = (char *)mpDetBareiss((matrix)v->Data());
4767  return FALSE;
4768}
4769static BOOLEAN jjidFreeModule(leftv res, leftv v)
4770{
4771  res->data = (char *)idFreeModule((int)(long)v->Data());
4772  return FALSE;
4773}
4774static BOOLEAN jjidVec2Ideal(leftv res, leftv v)
4775{
4776  res->data = (char *)idVec2Ideal((poly)v->Data());
4777  return FALSE;
4778}
4779static BOOLEAN jjrCharStr(leftv res, leftv v)
4780{
4781  res->data = rCharStr((ring)v->Data());
4782  return FALSE;
4783}
4784#ifndef MDEBUG
4785static BOOLEAN jjpHead(leftv res, leftv v)
4786{
4787  res->data = (char *)pHead((poly)v->Data());
4788  return FALSE;
4789}
4790#endif
4791static BOOLEAN jjidHead(leftv res, leftv v)
4792{
4793  res->data = (char *)idHead((ideal)v->Data());
4794  return FALSE;
4795}
4796static BOOLEAN jjidMaxIdeal(leftv res, leftv v)
4797{
4798  res->data = (char *)idMaxIdeal((int)(long)v->Data());
4799  return FALSE;
4800}
4801static BOOLEAN jjidMinBase(leftv res, leftv v)
4802{
4803  res->data = (char *)idMinBase((ideal)v->Data());
4804  return FALSE;
4805}
4806static BOOLEAN jjsyMinBase(leftv res, leftv v)
4807{
4808  res->data = (char *)syMinBase((ideal)v->Data());
4809  return FALSE;
4810}
4811static BOOLEAN jjpMaxComp(leftv res, leftv v)
4812{
4813  res->data = (char *)pMaxComp((poly)v->Data());
4814  return FALSE;
4815}
4816static BOOLEAN jjmpTrace(leftv res, leftv v)
4817{
4818  res->data = (char *)mpTrace((matrix)v->Data());
4819  return FALSE;
4820}
4821static BOOLEAN jjmpTransp(leftv res, leftv v)
4822{
4823  res->data = (char *)mpTransp((matrix)v->Data());
4824  return FALSE;
4825}
4826static BOOLEAN jjrOrdStr(leftv res, leftv v)
4827{
4828  res->data = rOrdStr((ring)v->Data());
4829  return FALSE;
4830}
4831static BOOLEAN jjrVarStr(leftv res, leftv v)
4832{
4833  res->data = rVarStr((ring)v->Data());
4834  return FALSE;
4835}
4836static BOOLEAN jjrParStr(leftv res, leftv v)
4837{
4838  res->data = rParStr((ring)v->Data());
4839  return FALSE;
4840}
4841static BOOLEAN jjCOUNT_RES(leftv res, leftv v)
4842{
4843  res->data=(char *)sySize((syStrategy)v->Data());
4844  return FALSE;
4845}
4846static BOOLEAN jjDIM_R(leftv res, leftv v)
4847{
4848  res->data = (char *)syDim((syStrategy)v->Data());
4849  return FALSE;
4850}
4851static BOOLEAN jjidTransp(leftv res, leftv v)
4852{
4853  res->data = (char *)idTransp((ideal)v->Data());
4854  return FALSE;
4855}
4856#else
4857#define XS(A)          -((short)A)
4858#define jjstrlen       (proc1)strlen
4859#define jjpLength      (proc1)pLength
4860#define jjidElem       (proc1)idElem
4861#define jjmpDetBareiss (proc1)mpDetBareiss
4862#define jjidFreeModule (proc1)idFreeModule
4863#define jjidVec2Ideal  (proc1)idVec2Ideal
4864#define jjrCharStr     (proc1)rCharStr
4865#ifndef MDEBUG
4866#define jjpHead        (proc1)pHeadProc
4867#endif
4868#define jjidHead       (proc1)idHead
4869#define jjidMaxIdeal   (proc1)idMaxIdeal
4870#define jjidMinBase    (proc1)idMinBase
4871#define jjsyMinBase    (proc1)syMinBase
4872#define jjpMaxComp     (proc1)pMaxCompProc
4873#define jjmpTrace      (proc1)mpTrace
4874#define jjmpTransp     (proc1)mpTransp
4875#define jjrOrdStr      (proc1)rOrdStr
4876#define jjrVarStr      (proc1)rVarStr
4877#define jjrParStr      (proc1)rParStr
4878#define jjCOUNT_RES    (proc1)sySize
4879#define jjDIM_R        (proc1)syDim
4880#define jjidTransp     (proc1)idTransp
4881#endif
4882#endif
4883static BOOLEAN jjnInt(leftv res, leftv u)
4884{
4885  number n=(number)u->Data();
4886  res->data=(char *)(long)n_Int(n,currRing);
4887  return FALSE;
4888}
4889static BOOLEAN jjnlInt(leftv res, leftv u)
4890{
4891  number n=(number)u->Data();
4892  res->data=(char *)(long)nlInt(n,NULL /*dummy for nlInt*/);
4893  return FALSE;
4894}
4895/*=================== operations with 3 args.: static proc =================*/
4896/* must be ordered: first operations for chars (infix ops),
4897 * then alphabetically */
4898static BOOLEAN jjBRACK_S(leftv res, leftv u, leftv v,leftv w)
4899{
4900  char *s= (char *)u->Data();
4901  int   r = (int)(long)v->Data();
4902  int   c = (int)(long)w->Data();
4903  int l = strlen(s);
4904
4905  if ( (r<1) || (r>l) || (c<0) )
4906  {
4907    Werror("wrong range[%d,%d] in string %s",r,c,u->Fullname());
4908    return TRUE;
4909  }
4910  res->data = (char *)omAlloc((long)(c+1));
4911  sprintf((char *)res->data,"%-*.*s",c,c,s+r-1);
4912  return FALSE;
4913}
4914static BOOLEAN jjBRACK_Im(leftv res, leftv u, leftv v,leftv w)
4915{
4916  intvec *iv = (intvec *)u->Data();
4917  int   r = (int)(long)v->Data();
4918  int   c = (int)(long)w->Data();
4919  if ((r<1)||(r>iv->rows())||(c<1)||(c>iv->cols()))
4920  {
4921    Werror("wrong range[%d,%d] in intmat %s(%d x %d)",
4922           r,c,u->Fullname(),iv->rows(),iv->cols());
4923    return TRUE;
4924  }
4925  res->data=u->data; u->data=NULL;
4926  res->rtyp=u->rtyp; u->rtyp=0;
4927  res->name=u->name; u->name=NULL;
4928  res->attribute=u->attribute; u->attribute=NULL;
4929  Subexpr e=jjMakeSub(v);
4930          e->next=jjMakeSub(w);
4931  if (u->e==NULL) res->e=e;
4932  else
4933  {
4934    Subexpr h=u->e;
4935    while (h->next!=NULL) h=h->next;
4936    h->next=e;
4937    res->e=u->e;
4938    u->e=NULL;
4939  }
4940  return FALSE;
4941}
4942static BOOLEAN jjBRACK_Ma(leftv res, leftv u, leftv v,leftv w)
4943{
4944  matrix m= (matrix)u->Data();
4945  int   r = (int)(long)v->Data();
4946  int   c = (int)(long)w->Data();
4947  //Print("gen. elem %d, %d\n",r,c);
4948  if ((r<1)||(r>MATROWS(m))||(c<1)||(c>MATCOLS(m)))
4949  {
4950    Werror("wrong range[%d,%d] in matrix %s(%d x %d)",r,c,u->Fullname(),
4951      MATROWS(m),MATCOLS(m));
4952    return TRUE;
4953  }
4954  res->data=u->data; u->data=NULL;
4955  res->rtyp=u->rtyp; u->rtyp=0;
4956  res->name=u->name; u->name=NULL;
4957  res->attribute=u->attribute; u->attribute=NULL;
4958  Subexpr e=jjMakeSub(v);
4959          e->next=jjMakeSub(w);
4960  if (u->e==NULL)
4961    res->e=e;
4962  else
4963  {
4964    Subexpr h=u->e;
4965    while (h->next!=NULL) h=h->next;
4966    h->next=e;
4967    res->e=u->e;
4968    u->e=NULL;
4969  }
4970  return FALSE;
4971}
4972static BOOLEAN jjBRACK_Ma_I_IV(leftv res, leftv u, leftv v,leftv w)
4973{
4974  sleftv t;
4975  sleftv ut;
4976  leftv p=NULL;
4977  intvec *iv=(intvec *)w->Data();
4978  int l;
4979  BOOLEAN nok;
4980
4981  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
4982  {
4983    WerrorS("cannot build expression lists from unnamed objects");
4984    return TRUE;
4985  }
4986  memcpy(&ut,u,sizeof(ut));
4987  memset(&t,0,sizeof(t));
4988  t.rtyp=INT_CMD;
4989  for (l=0;l< iv->length(); l++)
4990  {
4991    t.data=(char *)(long)((*iv)[l]);
4992    if (p==NULL)
4993    {
4994      p=res;
4995    }
4996    else
4997    {
4998      p->next=(leftv)omAlloc0Bin(sleftv_bin);
4999      p=p->next;
5000    }
5001    memcpy(u,&ut,sizeof(ut));
5002    if (u->Typ() == MATRIX_CMD)
5003      nok=jjBRACK_Ma(p,u,v,&t);
5004    else /* INTMAT_CMD */
5005      nok=jjBRACK_Im(p,u,v,&t);
5006    if (nok)
5007    {
5008      while (res->next!=NULL)
5009      {
5010        p=res->next->next;
5011        omFreeBin((ADDRESS)res->next, sleftv_bin);
5012        // res->e aufraeumen !!!!
5013        res->next=p;
5014      }
5015      return TRUE;
5016    }
5017  }
5018  return FALSE;
5019}
5020static BOOLEAN jjBRACK_Ma_IV_I(leftv res, leftv u, leftv v,leftv w)
5021{
5022  sleftv t;
5023  sleftv ut;
5024  leftv p=NULL;
5025  intvec *iv=(intvec *)v->Data();
5026  int l;
5027  BOOLEAN nok;
5028
5029  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
5030  {
5031    WerrorS("cannot build expression lists from unnamed objects");
5032    return TRUE;
5033  }
5034  memcpy(&ut,u,sizeof(ut));
5035  memset(&t,0,sizeof(t));
5036  t.rtyp=INT_CMD;
5037  for (l=0;l< iv->length(); l++)
5038  {
5039    t.data=(char *)(long)((*iv)[l]);
5040    if (p==NULL)
5041    {
5042      p=res;
5043    }
5044    else
5045    {
5046      p->next=(leftv)omAlloc0Bin(sleftv_bin);
5047      p=p->next;
5048    }
5049    memcpy(u,&ut,sizeof(ut));
5050    if (u->Typ() == MATRIX_CMD)
5051      nok=jjBRACK_Ma(p,u,&t,w);
5052    else /* INTMAT_CMD */
5053      nok=jjBRACK_Im(p,u,&t,w);
5054    if (nok)
5055    {
5056      while (res->next!=NULL)
5057      {
5058        p=res->next->next;
5059        omFreeBin((ADDRESS)res->next, sleftv_bin);
5060        // res->e aufraeumen !!
5061        res->next=p;
5062      }
5063      return TRUE;
5064    }
5065  }
5066  return FALSE;
5067}
5068static BOOLEAN jjBRACK_Ma_IV_IV(leftv res, leftv u, leftv v,leftv w)
5069{
5070  sleftv t1,t2,ut;
5071  leftv p=NULL;
5072  intvec *vv=(intvec *)v->Data();
5073  intvec *wv=(intvec *)w->Data();
5074  int vl;
5075  int wl;
5076  BOOLEAN nok;
5077
5078  if ((u->rtyp!=IDHDL)||(u->e!=NULL))
5079  {
5080    WerrorS("cannot build expression lists from unnamed objects");
5081    return TRUE;
5082  }
5083  memcpy(&ut,u,sizeof(ut));
5084  memset(&t1,0,sizeof(sleftv));
5085  memset(&t2,0,sizeof(sleftv));
5086  t1.rtyp=INT_CMD;
5087  t2.rtyp=INT_CMD;
5088  for (vl=0;vl< vv->length(); vl++)
5089  {
5090    t1.data=(char *)(long)((*vv)[vl]);
5091    for (wl=0;wl< wv->length(); wl++)
5092    {
5093      t2.data=(char *)(long)((*wv)[wl]);
5094      if (p==NULL)
5095      {
5096        p=res;
5097      }
5098      else
5099      {
5100        p->next=(leftv)omAlloc0Bin(sleftv_bin);
5101        p=p->next;
5102      }
5103      memcpy(u,&ut,sizeof(ut));
5104      if (u->Typ() == MATRIX_CMD)
5105        nok=jjBRACK_Ma(p,u,&t1,&t2);
5106      else /* INTMAT_CMD */
5107        nok=jjBRACK_Im(p,u,&t1,&t2);
5108      if (nok)
5109      {
5110        res->CleanUp();
5111        return TRUE;
5112      }
5113    }
5114  }
5115  return FALSE;
5116}
5117static BOOLEAN jjPROC3(leftv res, leftv u, leftv v, leftv w)
5118{
5119  v->next=(leftv)omAllocBin(sleftv_bin);
5120  memcpy(v->next,w,sizeof(sleftv));
5121  memset(w,0,sizeof(sleftv));
5122  return jjPROC(res,u,v);
5123}
5124static BOOLEAN jjCALL3MANY(leftv res, leftv u, leftv v, leftv w)
5125{
5126  u->next=(leftv)omAllocBin(sleftv_bin);
5127  memcpy(u->next,v,sizeof(sleftv));
5128  u->next->next=(leftv)omAllocBin(sleftv_bin);
5129  memcpy(u->next->next,w,sizeof(sleftv));
5130  BOOLEAN r=iiExprArithM(res,u,iiOp);
5131  v->Init();
5132  w->Init();
5133  //w->rtyp=0; w->data=NULL;
5134  // iiExprArithM did the CleanUp
5135  return r;
5136}
5137static BOOLEAN jjBAREISS3(leftv res, leftv u, leftv v, leftv w)
5138{
5139  intvec *iv;
5140  ideal m;
5141  lists l=(lists)omAllocBin(slists_bin);
5142  int k=(int)(long)w->Data();
5143  if (k>=0)
5144  {
5145    smCallBareiss((ideal)u->Data(),(int)(long)v->Data(),(int)(long)w->Data(),m,&iv);
5146    l->Init(2);
5147    l->m[0].rtyp=MODUL_CMD;
5148    l->m[1].rtyp=INTVEC_CMD;
5149    l->m[0].data=(void *)m;
5150    l->m[1].data=(void *)iv;
5151  }
5152  else
5153  {
5154    m=smCallSolv((ideal)u->Data());
5155    l->Init(1);
5156    l->m[0].rtyp=IDEAL_CMD;
5157    l->m[0].data=(void *)m;
5158  }
5159  res->data = (char *)l;
5160  return FALSE;
5161}
5162static BOOLEAN jjCOEFFS3_Id(leftv res, leftv u, leftv v, leftv w)
5163{
5164  if ((w->rtyp!=IDHDL)||(w->e!=NULL))
5165  {
5166    WerrorS("3rd argument must be a name of a matrix");
5167    return TRUE;
5168  }
5169  ideal i=(ideal)u->Data();
5170  int rank=(int)i->rank;
5171  BOOLEAN r=jjCOEFFS_Id(res,u,v);
5172  if (r) return TRUE;
5173  mpMonomials((matrix)res->data, rank, pVar((poly)v->Data()),(matrix)w->Data());
5174  return FALSE;
5175}
5176static BOOLEAN jjCOEFFS3_KB(leftv res, leftv u, leftv v, leftv w)
5177{
5178  res->data=(void*)idCoeffOfKBase((ideal)(u->Data()),
5179           (ideal)(v->Data()),(poly)(w->Data()));
5180  return FALSE;
5181}
5182static BOOLEAN jjCOEFFS3_P(leftv res, leftv u, leftv v, leftv w)
5183{
5184  if ((w->rtyp!=IDHDL)||(w->e!=NULL))
5185  {
5186    WerrorS("3rd argument must be a name of a matrix");
5187    return TRUE;
5188  }
5189  // CopyD for POLY_CMD and VECTOR_CMD are identical:
5190  poly p=(poly)u->CopyD(POLY_CMD);
5191  ideal i=idInit(1,1);
5192  i->m[0]=p;
5193  sleftv t;
5194  memset(&t,0,sizeof(t));
5195  t.data=(char *)i;
5196  t.rtyp=IDEAL_CMD;
5197  int rank=1;
5198  if (u->Typ()==VECTOR_CMD)
5199  {
5200    i->rank=rank=pMaxComp(p);
5201    t.rtyp=MODUL_CMD;
5202  }
5203  BOOLEAN r=jjCOEFFS_Id(res,&t,v);
5204  t.CleanUp();
5205  if (r) return TRUE;
5206  mpMonomials((matrix)res->data, rank, pVar((poly)v->Data()),(matrix)w->Data());
5207  return FALSE;
5208}
5209static BOOLEAN jjELIMIN_HILB(leftv res, leftv u, leftv v, leftv w)
5210{
5211  res->data=(char *)idElimination((ideal)u->Data(),(poly)v->Data(),
5212    (intvec *)w->Data());
5213  //setFlag(res,FLAG_STD);
5214  return FALSE;
5215}
5216static BOOLEAN jjFIND3(leftv res, leftv u, leftv v, leftv w)
5217{
5218  /*4
5219  * look for the substring what in the string where
5220  * starting at position n
5221  * return the position of the first char of what in where
5222  * or 0
5223  */
5224  int n=(int)(long)w->Data();
5225  char *where=(char *)u->Data();
5226  char *what=(char *)v->Data();
5227  char *found;
5228  if ((1>n)||(n>(int)strlen(where)))
5229  {
5230    Werror("start position %d out of range",n);
5231    return TRUE;
5232  }
5233  found = strchr(where+n-1,*what);
5234  if (*(what+1)!='\0')
5235  {
5236    while((found !=NULL) && (strncmp(found+1,what+1,strlen(what+1))!=0))
5237    {
5238      found=strchr(found+1,*what);
5239    }
5240  }
5241  if (found != NULL)
5242  {
5243    res->data=(char *)((found-where)+1);
5244  }
5245  return FALSE;
5246}
5247static BOOLEAN jjFWALK3(leftv res, leftv u, leftv v, leftv w)
5248{
5249  if ((int)(long)w->Data()==0)
5250    res->data=(char *)walkProc(u,v);
5251  else
5252    res->data=(char *)fractalWalkProc(u,v);
5253  setFlag( res, FLAG_STD );
5254  return FALSE;
5255}
5256static BOOLEAN jjHILBERT3(leftv res, leftv u, leftv v, leftv w)
5257{
5258  assumeStdFlag(u);
5259  intvec *module_w=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
5260  intvec *wdegree=(intvec*)w->Data();
5261  if (wdegree->length()!=pVariables)
5262  {
5263    Werror("weight vector must have size %d, not %d",
5264           pVariables,wdegree->length());
5265    return TRUE;
5266  }
5267  intvec *iv=hFirstSeries((ideal)u->Data(),module_w,currQuotient,wdegree);
5268  switch((int)(long)v->Data())
5269  {
5270    case 1:
5271      res->data=(void *)iv;
5272      return FALSE;
5273    case 2:
5274      res->data=(void *)hSecondSeries(iv);
5275      delete iv;
5276      return FALSE;
5277  }
5278  WerrorS(feNotImplemented);
5279  delete iv;
5280  return TRUE;
5281}
5282static BOOLEAN jjHOMOG_ID_W(leftv res, leftv u, leftv v, leftv w)
5283{
5284  PrintS("TODO\n");
5285  int i=pVar((poly)v->Data());
5286  if (i==0)
5287  {
5288    WerrorS("ringvar expected");
5289    return TRUE;
5290  }
5291  poly p=pOne(); pSetExp(p,i,1); pSetm(p);
5292  int d=pWTotaldegree(p);
5293  pLmDelete(p);
5294  if (d==1)
5295    res->data = (char *)idHomogen((ideal)u->Data(),i);
5296  else
5297    WerrorS("variable must have weight 1");
5298  return (d!=1);
5299}
5300static BOOLEAN jjHOMOG_P_W(leftv res, leftv u, leftv v,leftv w)
5301{
5302  PrintS("TODO\n");
5303  int i=pVar((poly)v->Data());
5304  if (i==0)
5305  {
5306    WerrorS("ringvar expected");
5307    return TRUE;
5308  }
5309  poly p=pOne(); pSetExp(p,i,1); pSetm(p);
5310  int d=pWTotaldegree(p);
5311  pLmDelete(p);
5312  if (d==1)
5313    res->data = (char *)pHomogen((poly)u->Data(),i);
5314  else
5315    WerrorS("variable must have weight 1");
5316  return (d!=1);
5317}
5318static BOOLEAN jjINTMAT3(leftv res, leftv u, leftv v,leftv w)
5319{
5320  intvec* im= new intvec((int)(long)v->Data(),(int)(long)w->Data(), 0);
5321  intvec* arg = (intvec*) u->Data();
5322  int i, n = si_min(im->cols()*im->rows(), arg->cols()*arg->rows());
5323
5324  for (i=0; i<n; i++)
5325  {
5326    (*im)[i] = (*arg)[i];
5327  }
5328
5329  res->data = (char *)im;
5330  return FALSE;
5331}
5332static BOOLEAN jjJET_P_IV(leftv res, leftv u, leftv v, leftv w)
5333{
5334  short *iw=iv2array((intvec *)w->Data());
5335  res->data = (char *)ppJetW((poly)u->Data(),(int)(long)v->Data(),iw);
5336  omFreeSize((ADDRESS)iw,(pVariables+1)*sizeof(short));
5337  return FALSE;
5338}
5339static BOOLEAN jjJET_P_P(leftv res, leftv u, leftv v, leftv w)
5340{
5341  if (!pIsUnit((poly)v->Data()))
5342  {
5343    WerrorS("2nd argument must be a unit");
5344    return TRUE;
5345  }
5346  res->data = (char *)pSeries((int)(long)w->Data(),(poly)u->CopyD(),(poly)v->CopyD());
5347  return FALSE;
5348}
5349static BOOLEAN jjJET_ID_IV(leftv res, leftv u, leftv v, leftv w)
5350{
5351  res->data = (char *)idJetW((ideal)u->Data(),(int)(long)v->Data(),
5352                             (intvec *)w->Data());
5353  return FALSE;
5354}
5355static BOOLEAN jjJET_ID_M(leftv res, leftv u, leftv v, leftv w)
5356{
5357  if (!mpIsDiagUnit((matrix)v->Data()))
5358  {
5359    WerrorS("2nd argument must be a diagonal matrix of units");
5360    return TRUE;
5361  }
5362  res->data = (char *)idSeries((int)(long)w->Data(),(ideal)u->CopyD(),
5363                               (matrix)v->CopyD());
5364  return FALSE;
5365}
5366static BOOLEAN currRingIsOverIntegralDomain ()
5367{
5368  /* true for fields and Z, false otherwise */
5369  if (rField_is_Ring_PtoM()) return FALSE;
5370  if (rField_is_Ring_2toM()) return FALSE;
5371  if (rField_is_Ring_ModN()) return FALSE;
5372  return TRUE;
5373}
5374static BOOLEAN jjMINOR_M(leftv res, leftv v)
5375{
5376  /* Here's the use pattern for the minor command:
5377        minor ( matrix_expression m, int_expression minorSize,
5378                optional ideal_expression IasSB, optional int_expression k,
5379                optional string_expression algorithm,
5380                optional int_expression cachedMinors,
5381                optional int_expression cachedMonomials )
5382     This method here assumes that there are at least two arguments.
5383     - If IasSB is present, it must be a std basis. All minors will be
5384       reduced w.r.t. IasSB.
5385     - If k is absent, all non-zero minors will be computed.
5386       If k is present and k > 0, the first k non-zero minors will be
5387       computed.
5388       If k is present and k < 0, the first |k| minors (some of which
5389       may be zero) will be computed.
5390       If k is present and k = 0, an error is reported.
5391     - If algorithm is absent, all the following arguments must be absent too.
5392       In this case, a heuristic picks the best-suited algorithm (among
5393       Bareiss, Laplace, and Laplace with caching).
5394       If algorithm is present, it must be one of "Bareiss", "bareiss",
5395       "Laplace", "laplace", "Cache", "cache". In the cases "Cache" and
5396       "cache" two more arguments may be given, determining how many entries
5397       the cache may have at most, and how many cached monomials there are at
5398       most. (Cached monomials are counted over all cached polynomials.)
5399       If these two additional arguments are not provided, 200 and 100000
5400       will be used as defaults.
5401  */
5402  matrix m;
5403  leftv u=v->next;
5404  v->next=NULL;
5405  int v_typ=v->Typ();
5406  if (v_typ==MATRIX_CMD)
5407  {
5408     m = (const matrix)v->Data();
5409  }
5410  else
5411  {
5412    if (v_typ==0)
5413    {
5414      Werror("`%s` is undefined",v->Fullname());
5415      return TRUE;
5416    }
5417    // try to convert to MATRIX:
5418    int ii=iiTestConvert(v_typ,MATRIX_CMD);
5419    BOOLEAN bo;
5420    sleftv tmp;
5421    if (ii>0) bo=iiConvert(v_typ,MATRIX_CMD,ii,v,&tmp);
5422    else bo=TRUE;
5423    if (bo)
5424    {
5425      Werror("cannot convert %s to matrix",Tok2Cmdname(v_typ));
5426      return TRUE;
5427    }
5428    m=(matrix)tmp.data;
5429  }
5430  const int mk = (const int)(long)u->Data();
5431  bool noIdeal = true; bool noK = true; bool noAlgorithm = true;
5432  bool noCacheMinors = true; bool noCacheMonomials = true;
5433  ideal IasSB; int k; char* algorithm; int cacheMinors; int cacheMonomials;
5434
5435  /* here come the different cases of correct argument sets */
5436  if ((u->next != NULL) && (u->next->Typ() == IDEAL_CMD))
5437  {
5438    IasSB = (ideal)u->next->Data();
5439    noIdeal = false;
5440    if ((u->next->next != NULL) && (u->next->next->Typ() == INT_CMD))
5441    {
5442      k = (int)(long)u->next->next->Data();
5443      noK = false;
5444      assume(k != 0);
5445      if ((u->next->next->next != NULL) &&
5446          (u->next->next->next->Typ() == STRING_CMD))
5447      {
5448        algorithm = (char*)u->next->next->next->Data();
5449        noAlgorithm = false;
5450        if ((u->next->next->next->next != NULL) &&
5451            (u->next->next->next->next->Typ() == INT_CMD))
5452        {
5453          cacheMinors = (int)(long)u->next->next->next->next->Data();
5454          noCacheMinors = false;
5455          if ((u->next->next->next->next->next != NULL) &&
5456              (u->next->next->next->next->next->Typ() == INT_CMD))
5457          {
5458            cacheMonomials =
5459               (int)(long)u->next->next->next->next->next->Data();
5460            noCacheMonomials = false;
5461          }
5462        }
5463      }
5464    }
5465  }
5466  else if ((u->next != NULL) && (u->next->Typ() == INT_CMD))
5467  {
5468    k = (int)(long)u->next->Data();
5469    noK = false;
5470    assume(k != 0);
5471    if ((u->next->next != NULL) && (u->next->next->Typ() == STRING_CMD))
5472    {
5473      algorithm = (char*)u->next->next->Data();
5474      noAlgorithm = false;
5475      if ((u->next->next->next != NULL) &&
5476          (u->next->next->next->Typ() == INT_CMD))
5477      {
5478        cacheMinors = (int)(long)u->next->next->next->Data();
5479        noCacheMinors = false;
5480        if ((u->next->next->next->next != NULL) &&
5481            (u->next->next->next->next->Typ() == INT_CMD))
5482        {
5483          cacheMonomials = (int)(long)u->next->next->next->next->Data();
5484          noCacheMonomials = false;
5485        }
5486      }
5487    }
5488  }
5489  else if ((u->next != NULL) && (u->next->Typ() == STRING_CMD))
5490  {
5491    algorithm = (char*)u->next->Data();
5492    noAlgorithm = false;
5493    if ((u->next->next != NULL) && (u->next->next->Typ() == INT_CMD))
5494    {
5495      cacheMinors = (int)(long)u->next->next->Data();
5496      noCacheMinors = false;
5497      if ((u->next->next->next != NULL) &&
5498          (u->next->next->next->Typ() == INT_CMD))
5499      {
5500        cacheMonomials = (int)(long)u->next->next->next->Data();
5501        noCacheMonomials = false;
5502      }
5503    }
5504  }
5505
5506  /* upper case conversion for the algorithm if present */
5507  if (!noAlgorithm)
5508  {
5509    if (strcmp(algorithm, "bareiss") == 0)
5510      algorithm = (char*)"Bareiss";
5511    if (strcmp(algorithm, "laplace") == 0)
5512      algorithm = (char*)"Laplace";
5513    if (strcmp(algorithm, "cache") == 0)
5514      algorithm = (char*)"Cache";
5515  }
5516
5517  v->next=u;
5518  /* here come some tests */
5519  if (!noIdeal)
5520  {
5521    assumeStdFlag(u->next);
5522  }
5523  if ((!noK) && (k == 0))
5524  {
5525    WerrorS("Provided number of minors to be computed is zero.");
5526    return TRUE;
5527  }
5528  if ((!noAlgorithm) && (strcmp(algorithm, "Bareiss") != 0)
5529      && (strcmp(algorithm, "Laplace") != 0)
5530      && (strcmp(algorithm, "Cache") != 0))
5531  {
5532    WerrorS("Expected as algorithm one of 'B/bareiss', 'L/laplace', or 'C/cache'.");
5533    return TRUE;
5534  }
5535  if ((!noAlgorithm) && (strcmp(algorithm, "Bareiss") == 0)
5536      && (!currRingIsOverIntegralDomain()))
5537  {
5538    Werror("Bareiss algorithm not defined over coefficient rings %s",
5539           "with zero divisors.");
5540    return TRUE;
5541  }
5542  if ((mk < 1) || (mk > m->rows()) || (mk > m->cols()))
5543  {
5544    Werror("invalid size of minors: %d (matrix is (%d x %d))", mk,
5545           m->rows(), m->cols());
5546    return TRUE;
5547  }
5548  if ((!noAlgorithm) && (strcmp(algorithm, "Cache") == 0)
5549      && (noCacheMinors || noCacheMonomials))
5550  {
5551    cacheMinors = 200;
5552    cacheMonomials = 100000;
5553  }
5554
5555  /* here come the actual procedure calls */
5556  if (noAlgorithm)
5557    res->data = getMinorIdealHeuristic(m, mk, (noK ? 0 : k),
5558                                       (noIdeal ? 0 : IasSB), false);
5559  else if (strcmp(algorithm, "Cache") == 0)
5560    res->data = getMinorIdealCache(m, mk, (noK ? 0 : k),
5561                                   (noIdeal ? 0 : IasSB), 3, cacheMinors,
5562                                   cacheMonomials, false);
5563  else
5564    res->data = getMinorIdeal(m, mk, (noK ? 0 : k), algorithm,
5565                              (noIdeal ? 0 : IasSB), false);
5566  if (v_typ!=MATRIX_CMD) idDelete((ideal *)&m);
5567  res->rtyp = IDEAL_CMD;
5568  return FALSE;
5569}
5570static BOOLEAN jjNEWSTRUCT3(leftv res, leftv u, leftv v, leftv w)
5571{
5572  // u: the name of the new type
5573  // v: the parent type
5574  // w: the elements
5575  newstruct_desc d=newstructChildFromString((const char *)v->Data(),
5576                                            (const char *)w->Data());
5577  if (d!=NULL) newstruct_setup((const char *)u->Data(),d);
5578  return d==NULL;
5579}
5580static BOOLEAN jjPREIMAGE(leftv res, leftv u, leftv v, leftv w)
5581{
5582  // handles preimage(r,phi,i) and kernel(r,phi)
5583  idhdl h;
5584  ring rr;
5585  map mapping;
5586  BOOLEAN kernel_cmd= (iiOp==KERNEL_CMD);
5587
5588  if ((v->name==NULL) || (!kernel_cmd && (w->name==NULL)))
5589  {
5590    WerrorS("2nd/3rd arguments must have names");
5591    return TRUE;
5592  }
5593  rr=(ring)u->Data();
5594  const char *ring_name=u->Name();
5595  if ((h=rr->idroot->get(v->name,myynest))!=NULL)
5596  {
5597    if (h->typ==MAP_CMD)
5598    {
5599      mapping=IDMAP(h);
5600      idhdl preim_ring=IDROOT->get(mapping->preimage,myynest);
5601      if ((preim_ring==NULL)
5602      || (IDRING(preim_ring)!=currRing))
5603      {
5604        Werror("preimage ring `%s` is not the basering",mapping->preimage);
5605        return TRUE;
5606      }
5607    }
5608    else if (h->typ==IDEAL_CMD)
5609    {
5610      mapping=IDMAP(h);
5611    }
5612    else
5613    {
5614      Werror("`%s` is no map nor ideal",IDID(h));
5615      return TRUE;
5616    }
5617  }
5618  else
5619  {
5620    Werror("`%s` is not defined in `%s`",v->name,ring_name);
5621    return TRUE;
5622  }
5623  ideal image;
5624  if (kernel_cmd) image=idInit(1,1);
5625  else
5626  {
5627    if ((h=rr->idroot->get(w->name,myynest))!=NULL)
5628    {
5629      if (h->typ==IDEAL_CMD)
5630      {
5631        image=IDIDEAL(h);
5632      }
5633      else
5634      {
5635        Werror("`%s` is no ideal",IDID(h));
5636        return TRUE;
5637      }
5638    }
5639    else
5640    {
5641      Werror("`%s` is not defined in `%s`",w->name,ring_name);
5642      return TRUE;
5643    }
5644  }
5645  if (((currRing->qideal!=NULL) && (rHasLocalOrMixedOrdering_currRing()))
5646  || ((rr->qideal!=NULL) && (rHasLocalOrMixedOrdering(rr))))
5647  {
5648    WarnS("preimage in local qring may be wrong: use Ring::preimageLoc instead");
5649  }
5650  res->data=(char *)maGetPreimage(rr,mapping,image);
5651  if (kernel_cmd) idDelete(&image);
5652  return (res->data==NULL/* is of type ideal, should not be NULL*/);
5653}
5654static BOOLEAN jjRANDOM_Im(leftv res, leftv u, leftv v, leftv w)
5655{
5656  int di, k;
5657  int i=(int)(long)u->Data();
5658  int r=(int)(long)v->Data();
5659  int c=(int)(long)w->Data();
5660  if ((r<=0) || (c<=0)) return TRUE;
5661  intvec *iv = new intvec(r, c, 0);
5662  if (iv->rows()==0)
5663  {
5664    delete iv;
5665    return TRUE;
5666  }
5667  if (i!=0)
5668  {
5669    if (i<0) i = -i;
5670    di = 2 * i + 1;
5671    for (k=0; k<iv->length(); k++)
5672    {
5673      (*iv)[k] = ((siRand() % di) - i);
5674    }
5675  }
5676  res->data = (char *)iv;
5677  return FALSE;
5678}
5679static BOOLEAN jjSUBST_Test(leftv v,leftv w,
5680  int &ringvar, poly &monomexpr)
5681{
5682  monomexpr=(poly)w->Data();
5683  poly p=(poly)v->Data();
5684  #if 0
5685  if (pLength(monomexpr)>1)
5686  {
5687    Werror("`%s` substitutes a ringvar only by a term",
5688      Tok2Cmdname(SUBST_CMD));
5689    return TRUE;
5690  }
5691  #endif
5692  if (!(ringvar=pVar(p)))
5693  {
5694    if (rField_is_Extension(currRing))
5695    {
5696      assume(currRing->algring!=NULL);
5697      lnumber n=(lnumber)pGetCoeff(p);
5698      ringvar=-p_Var(n->z,currRing->algring);
5699    }
5700    if(ringvar==0)
5701    {
5702      WerrorS("ringvar/par expected");
5703      return TRUE;
5704    }
5705  }
5706  return FALSE;
5707}
5708static BOOLEAN jjSUBST_P(leftv res, leftv u, leftv v,leftv w)
5709{
5710  int ringvar;
5711  poly monomexpr;
5712  BOOLEAN nok=jjSUBST_Test(v,w,ringvar,monomexpr);
5713  if (nok) return TRUE;
5714  poly p=(poly)u->Data();
5715  if (ringvar>0)
5716  {
5717    if ((monomexpr!=NULL) && (p!=NULL) && (pTotaldegree(p)!=0) &&
5718    ((unsigned long)pTotaldegree(monomexpr) > (currRing->bitmask / (unsigned long)pTotaldegree(p))))
5719    {
5720      Warn("possible OVERFLOW in subst, max exponent is %ld",currRing->bitmask);
5721      //return TRUE;
5722    }
5723    if ((monomexpr==NULL)||(pNext(monomexpr)==NULL))
5724      res->data = pSubst((poly)u->CopyD(res->rtyp),ringvar,monomexpr);
5725    else
5726      res->data= pSubstPoly(p,ringvar,monomexpr);
5727  }
5728  else
5729  {
5730    res->data=pSubstPar(p,-ringvar,monomexpr);
5731  }
5732  return FALSE;
5733}
5734static BOOLEAN jjSUBST_Id(leftv res, leftv u, leftv v,leftv w)
5735{
5736  int ringvar;
5737  poly monomexpr;
5738  BOOLEAN nok=jjSUBST_Test(v,w,ringvar,monomexpr);
5739  if (nok) return TRUE;
5740  if (ringvar>0)
5741  {
5742    if ((monomexpr==NULL)||(pNext(monomexpr)==NULL))
5743      res->data = idSubst((ideal)u->CopyD(res->rtyp),ringvar,monomexpr);
5744    else
5745      res->data = idSubstPoly((ideal)u->Data(),ringvar,monomexpr);
5746  }
5747  else
5748  {
5749    res->data = idSubstPar((ideal)u->Data(),-ringvar,monomexpr);
5750  }
5751  return FALSE;
5752}
5753// we do not want to have jjSUBST_Id_X inlined:
5754static BOOLEAN jjSUBST_Id_X(leftv res, leftv u, leftv v,leftv w,
5755                            int input_type);
5756static BOOLEAN jjSUBST_Id_I(leftv res, leftv u, leftv v,leftv w)
5757{
5758  return jjSUBST_Id_X(res,u,v,w,INT_CMD);
5759}
5760static BOOLEAN jjSUBST_Id_N(leftv res, leftv u, leftv v,leftv w)
5761{
5762  return jjSUBST_Id_X(res,u,v,w,NUMBER_CMD);
5763}
5764static BOOLEAN jjSUBST_Id_X(leftv res, leftv u, leftv v,leftv w, int input_type)
5765{
5766  sleftv tmp;
5767  memset(&tmp,0,sizeof(tmp));
5768  // do not check the result, conversion from int/number to poly works always
5769  iiConvert(input_type,POLY_CMD,iiTestConvert(input_type,POLY_CMD),w,&tmp);
5770  BOOLEAN b=jjSUBST_Id(res,u,v,&tmp);
5771  tmp.CleanUp();
5772  return b;
5773}
5774static BOOLEAN jjMATRIX_Id(leftv res, leftv u, leftv v,leftv w)
5775{
5776  matrix m=mpNew((int)(long)v->Data(),(int)(long)w->Data());
5777  ideal I=(ideal)u->CopyD(IDEAL_CMD);
5778  int i=si_min(IDELEMS(I),(int)(long)v->Data()*(int)(long)w->Data());
5779  //for(i=i-1;i>=0;i--)
5780  //{
5781  //  m->m[i]=I->m[i];
5782  //  I->m[i]=NULL;
5783  //}
5784  memcpy4(m->m,I->m,i*sizeof(poly));
5785  memset(I->m,0,i*sizeof(poly));
5786  idDelete(&I);
5787  res->data = (char *)m;
5788  return FALSE;
5789}
5790static BOOLEAN jjMATRIX_Mo(leftv res, leftv u, leftv v,leftv w)
5791{
5792  res->data = (char *)idModule2formatedMatrix((ideal)u->CopyD(MODUL_CMD),
5793           (int)(long)v->Data(),(int)(long)w->Data());
5794  return FALSE;
5795}
5796static BOOLEAN jjMATRIX_Ma(leftv res, leftv u, leftv v,leftv w)
5797{
5798  matrix m=mpNew((int)(long)v->Data(),(int)(long)w->Data());
5799  matrix I=(matrix)u->CopyD(MATRIX_CMD);
5800  int r=si_min(MATROWS(I),(int)(long)v->Data());
5801  int c=si_min(MATCOLS(I),(int)(long)w->Data());
5802  int i,j;
5803  for(i=r;i>0;i--)
5804  {
5805    for(j=c;j>0;j--)
5806    {
5807      MATELEM(m,i,j)=MATELEM(I,i,j);
5808      MATELEM(I,i,j)=NULL;
5809    }
5810  }
5811  idDelete((ideal *)&I);
5812  res->data = (char *)m;
5813  return FALSE;
5814}
5815static BOOLEAN jjLIFT3(leftv res, leftv u, leftv v, leftv w)
5816{
5817  if (w->rtyp!=IDHDL) return TRUE;
5818  BITSET save_test=test;
5819  int ul= IDELEMS((ideal)u->Data());
5820  int vl= IDELEMS((ideal)v->Data());
5821  ideal m
5822    = idLift((ideal)u->Data(),(ideal)v->Data(),NULL,FALSE,hasFlag(u,FLAG_STD),
5823             FALSE, (matrix *)(&(IDMATRIX((idhdl)(w->data)))));
5824  res->data = (char *)idModule2formatedMatrix(m,ul,vl);
5825  test=save_test;
5826  return FALSE;
5827}
5828static BOOLEAN jjLIFTSTD3(leftv res, leftv u, leftv v, leftv w)
5829{
5830  if ((v->rtyp!=IDHDL)||(v->e!=NULL)) return TRUE;
5831  if ((w->rtyp!=IDHDL)||(w->e!=NULL)) return TRUE;
5832  idhdl hv=(idhdl)v->data;
5833  idhdl hw=(idhdl)w->data;
5834  // CopyD for IDEAL_CMD and MODUL_CMD are identical:
5835  res->data = (char *)idLiftStd((ideal)u->Data(),
5836                                &(hv->data.umatrix),testHomog,
5837                                &(hw->data.uideal));
5838  setFlag(res,FLAG_STD); v->flag=0; w->flag=0;
5839  return FALSE;
5840}
5841static BOOLEAN jjREDUCE3_CP(leftv res, leftv u, leftv v, leftv w)
5842{
5843  assumeStdFlag(v);
5844  if (!idIsZeroDim((ideal)v->Data()))
5845  {
5846    Werror("`%s` must be 0-dimensional",v->Name());
5847    return TRUE;
5848  }
5849  res->data = (char *)redNF((ideal)v->CopyD(),(poly)u->CopyD(),
5850    (poly)w->CopyD());
5851  return FALSE;
5852}
5853static BOOLEAN jjREDUCE3_CID(leftv res, leftv u, leftv v, leftv w)
5854{
5855  assumeStdFlag(v);
5856  if (!idIsZeroDim((ideal)v->Data()))
5857  {
5858    Werror("`%s` must be 0-dimensional",v->Name());
5859    return TRUE;
5860  }
5861  res->data = (char *)redNF((ideal)v->CopyD(),(ideal)u->CopyD(),
5862    (matrix)w->CopyD());
5863  return FALSE;
5864}
5865static BOOLEAN jjREDUCE3_P(leftv res, leftv u, leftv v, leftv w)
5866{
5867  assumeStdFlag(v);
5868  res->data = (char *)kNF((ideal)v->Data(),currQuotient,(poly)u->Data(),
5869    0,(int)(long)w->Data());
5870  return FALSE;
5871}
5872static BOOLEAN jjREDUCE3_ID(leftv res, leftv u, leftv v, leftv w)
5873{
5874  assumeStdFlag(v);
5875  res->data = (char *)kNF((ideal)v->Data(),currQuotient,(ideal)u->Data(),
5876    0,(int)(long)w->Data());
5877  return FALSE;
5878}
5879#ifdef OLD_RES
5880static BOOLEAN jjRES3(leftv res, leftv u, leftv v, leftv w)
5881{
5882  int maxl=(int)v->Data();
5883  ideal u_id=(ideal)u->Data();
5884  int l=0;
5885  resolvente r;
5886  intvec **weights=NULL;
5887  int wmaxl=maxl;
5888  maxl--;
5889  if ((maxl==-1) && (iiOp!=MRES_CMD))
5890    maxl = pVariables-1;
5891  if ((iiOp == RES_CMD) || (iiOp == MRES_CMD))
5892  {
5893    intvec * iv=(intvec*)atGet(u,"isHomog",INTVEC_CMD);
5894    if (iv!=NULL)
5895    {
5896      l=1;
5897      if (!idTestHomModule(u_id,currQuotient,iv))
5898      {
5899        WarnS("wrong weights");
5900        iv=NULL;
5901      }
5902      else
5903      {
5904        weights = (intvec**)omAlloc0Bin(char_ptr_bin);
5905        weights[0] = ivCopy(iv);
5906      }
5907    }
5908    r=syResolvente(u_id,maxl,&l, &weights, iiOp==MRES_CMD);
5909  }
5910  else
5911    r=sySchreyerResolvente((ideal)u->Data(),maxl+1,&l);
5912  if (r==NULL) return TRUE;
5913  int t3=u->Typ();
5914  iiMakeResolv(r,l,wmaxl,w->name,t3,weights);
5915  return FALSE;
5916}
5917#endif
5918static BOOLEAN jjRING3(leftv res, leftv u, leftv v, leftv w)
5919{
5920  res->data=(void *)rInit(u,v,w);
5921  return (res->data==NULL);
5922}
5923static BOOLEAN jjSTATUS3(leftv res, leftv u, leftv v, leftv w)
5924{
5925  int yes;
5926  jjSTATUS2(res, u, v);
5927  yes = (strcmp((char *) res->data, (char *) w->Data()) == 0);
5928  omFree((ADDRESS) res->data);
5929  res->data = (void *)(long)yes;
5930  return FALSE;
5931}
5932static BOOLEAN jjSTD_HILB_W(leftv res, leftv u, leftv v, leftv w)
5933{
5934  intvec *vw=(intvec *)w->Data(); // weights of vars
5935  if (vw->length()!=currRing->N)
5936  {
5937    Werror("%d weights for %d variables",vw->length(),currRing->N);
5938    return TRUE;
5939  }
5940  ideal result;
5941  intvec *ww=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
5942  tHomog hom=testHomog;
5943  ideal u_id=(ideal)(u->Data());
5944  if (ww!=NULL)
5945  {
5946    if (!idTestHomModule(u_id,currQuotient,ww))
5947    {
5948      WarnS("wrong weights");
5949      ww=NULL;
5950    }
5951    else
5952    {
5953      ww=ivCopy(ww);
5954      hom=isHomog;
5955    }
5956  }
5957  result=kStd(u_id,
5958              currQuotient,
5959              hom,
5960              &ww,                  // module weights
5961              (intvec *)v->Data(),  // hilbert series
5962              0,0,                  // syzComp, newIdeal
5963              vw);                  // weights of vars
5964  idSkipZeroes(result);
5965  res->data = (char *)result;
5966  setFlag(res,FLAG_STD);
5967  if (ww!=NULL) atSet(res,omStrDup("isHomog"),ww,INTVEC_CMD);
5968  return FALSE;
5969}
5970
5971/*=================== operations with many arg.: static proc =================*/
5972/* must be ordered: first operations for chars (infix ops),
5973 * then alphabetically */
5974static BOOLEAN jjBREAK0(leftv res, leftv v)
5975{
5976#ifdef HAVE_SDB
5977  sdb_show_bp();
5978#endif
5979  return FALSE;
5980}
5981static BOOLEAN jjBREAK1(leftv res, leftv v)
5982{
5983#ifdef HAVE_SDB
5984  if(v->Typ()==PROC_CMD)
5985  {
5986    int lineno=0;
5987    if((v->next!=NULL) && (v->next->Typ()==INT_CMD))
5988    {
5989      lineno=(int)(long)v->next->Data();
5990    }
5991    return sdb_set_breakpoint(v->Name(),lineno);
5992  }
5993  return TRUE;
5994#else
5995 return FALSE;
5996#endif
5997}
5998static BOOLEAN jjCALL1ARG(leftv res, leftv v)
5999{
6000  return iiExprArith1(res,v,iiOp);
6001}
6002static BOOLEAN jjCALL2ARG(leftv res, leftv u)
6003{
6004  leftv v=u->next;
6005  u->next=NULL;
6006  BOOLEAN b=iiExprArith2(res,u,iiOp,v, (iiOp > 255));
6007  u->next=v;
6008  return b;
6009}
6010static BOOLEAN jjCALL3ARG(leftv res, leftv u)
6011{
6012  leftv v = u->next;
6013  leftv w = v->next;
6014  u->next = NULL;
6015  v->next = NULL;
6016  BOOLEAN b = iiExprArith3(res, iiOp, u, v, w);
6017  u->next = v;
6018  v->next = w;
6019  return b;
6020}
6021
6022static BOOLEAN jjCOEF_M(leftv res, leftv v)
6023{
6024  if((v->Typ() != VECTOR_CMD)
6025  || (v->next->Typ() != POLY_CMD)
6026  || (v->next->next->Typ() != MATRIX_CMD)
6027  || (v->next->next->next->Typ() != MATRIX_CMD))
6028     return TRUE;
6029  if (v->next->next->rtyp!=IDHDL) return TRUE;
6030  idhdl c=(idhdl)v->next->next->data;
6031  if (v->next->next->next->rtyp!=IDHDL) return TRUE;
6032  idhdl m=(idhdl)v->next->next->next->data;
6033  idDelete((ideal *)&(c->data.uideal));
6034  idDelete((ideal *)&(m->data.uideal));
6035  mpCoef2((poly)v->Data(),(poly)v->next->Data(),
6036    (matrix *)&(c->data.umatrix),(matrix *)&(m->data.umatrix));
6037  return FALSE;
6038}
6039
6040static BOOLEAN jjDIVISION4(leftv res, leftv v)
6041{ // may have 3 or 4 arguments
6042  leftv v1=v;
6043  leftv v2=v1->next;
6044  leftv v3=v2->next;
6045  leftv v4=v3->next;
6046  assumeStdFlag(v2);
6047
6048  int i1=iiTestConvert(v1->Typ(),MODUL_CMD);
6049  int i2=iiTestConvert(v2->Typ(),MODUL_CMD);
6050
6051  if((i1==0)||(i2==0)
6052  ||(v3->Typ()!=INT_CMD)||((v4!=NULL)&&(v4->Typ()!=INTVEC_CMD)))
6053  {
6054    WarnS("<module>,<module>,<int>[,<intvec>] expected!");
6055    return TRUE;
6056  }
6057
6058  sleftv w1,w2;
6059  iiConvert(v1->Typ(),MODUL_CMD,i1,v1,&w1);
6060  iiConvert(v2->Typ(),MODUL_CMD,i2,v2,&w2);
6061  ideal P=(ideal)w1.Data();
6062  ideal Q=(ideal)w2.Data();
6063
6064  int n=(int)(long)v3->Data();
6065  short *w=NULL;
6066  if(v4!=NULL)
6067  {
6068    w=iv2array((intvec *)v4->Data());
6069    short *w0=w+1;
6070    int i=pVariables;
6071    while(i>0&&*w0>0)
6072    {
6073      w0++;
6074      i--;
6075    }
6076    if(i>0)
6077      WarnS("not all weights are positive!");
6078  }
6079
6080  matrix T;
6081  ideal R;
6082  idLiftW(P,Q,n,T,R,w);
6083
6084  w1.CleanUp();
6085  w2.CleanUp();
6086  if(w!=NULL)
6087    omFree(w);
6088
6089  lists L=(lists) omAllocBin(slists_bin);
6090  L->Init(2);
6091  L->m[1].rtyp=v1->Typ();
6092  if(v1->Typ()==POLY_CMD||v1->Typ()==VECTOR_CMD)
6093  {
6094    if(v1->Typ()==POLY_CMD)
6095      pShift(&R->m[0],-1);
6096    L->m[1].data=(void *)R->m[0];
6097    R->m[0]=NULL;
6098    idDelete(&R);
6099  }
6100  else if(v1->Typ()==IDEAL_CMD||v1->Typ()==MATRIX_CMD)
6101    L->m[1].data=(void *)idModule2Matrix(R);
6102  else
6103  {
6104    L->m[1].rtyp=MODUL_CMD;
6105    L->m[1].data=(void *)R;
6106  }
6107  L->m[0].rtyp=MATRIX_CMD;
6108  L->m[0].data=(char *)T;
6109
6110  res->data=L;
6111  res->rtyp=LIST_CMD;
6112
6113  return FALSE;
6114}
6115
6116//static BOOLEAN jjEXPORTTO_M(leftv res, leftv u)
6117//{
6118//  int l=u->listLength();
6119//  if (l<2) return TRUE;
6120//  BOOLEAN b;
6121//  leftv v=u->next;
6122//  leftv zz=v;
6123//  leftv z=zz;
6124//  u->next=NULL;
6125//  do
6126//  {
6127//    leftv z=z->next;
6128//    b=iiExprArith2(res,u,iiOp,z, (iiOp > 255));
6129//    if (b) break;
6130//  } while (z!=NULL);
6131//  u->next=zz;
6132//  return b;
6133//}
6134static BOOLEAN jjIDEAL_PL(leftv res, leftv v)
6135{
6136  int s=1;
6137  leftv h=v;
6138  if (h!=NULL) s=exprlist_length(h);
6139  ideal id=idInit(s,1);
6140  int rank=1;
6141  int i=0;
6142  poly p;
6143  while (h!=NULL)
6144  {
6145    switch(h->Typ())
6146    {
6147      case POLY_CMD:
6148      {
6149        p=(poly)h->CopyD(POLY_CMD);
6150        break;
6151      }
6152      case INT_CMD:
6153      {
6154        number n=nInit((int)(long)h->Data());
6155        if (!nIsZero(n))
6156        {
6157          p=pNSet(n);
6158        }
6159        else
6160        {
6161          p=NULL;
6162          nDelete(&n);
6163        }
6164        break;
6165      }
6166      case BIGINT_CMD:
6167      {
6168        number b=(number)h->Data();
6169        number n=nInit_bigint(b);
6170        if (!nIsZero(n))
6171        {
6172          p=pNSet(n);
6173        }
6174        else
6175        {
6176          p=NULL;
6177          nDelete(&n);
6178        }
6179        break;
6180      }
6181      case NUMBER_CMD:
6182      {
6183        number n=(number)h->CopyD(NUMBER_CMD);
6184        if (!nIsZero(n))
6185        {
6186          p=pNSet(n);
6187        }
6188        else
6189        {
6190          p=NULL;
6191          nDelete(&n);
6192        }
6193        break;
6194      }
6195      case VECTOR_CMD:
6196      {
6197        p=(poly)h->CopyD(VECTOR_CMD);
6198        if (iiOp!=MODUL_CMD)
6199        {
6200          idDelete(&id);
6201          pDelete(&p);
6202          return TRUE;
6203        }
6204        rank=si_max(rank,(int)pMaxComp(p));
6205        break;
6206      }
6207      default:
6208      {
6209        idDelete(&id);
6210        return TRUE;
6211      }
6212    }
6213    if ((iiOp==MODUL_CMD)&&(p!=NULL)&&(pGetComp(p)==0))
6214    {
6215      pSetCompP(p,1);
6216    }
6217    id->m[i]=p;
6218    i++;
6219    h=h->next;
6220  }
6221  id->rank=rank;
6222  res->data=(char *)id;
6223  return FALSE;
6224}
6225static BOOLEAN jjINTERSECT_PL(leftv res, leftv v)
6226{
6227  leftv h=v;
6228  int l=v->listLength();
6229  resolvente r=(resolvente)omAlloc0(l*sizeof(ideal));
6230  BOOLEAN *copied=(BOOLEAN *)omAlloc0(l*sizeof(BOOLEAN));
6231  int t=0;
6232  // try to convert to IDEAL_CMD
6233  while (h!=NULL)
6234  {
6235    if (iiTestConvert(h->Typ(),IDEAL_CMD)!=0)
6236    {
6237      t=IDEAL_CMD;
6238    }
6239    else break;
6240    h=h->next;
6241  }
6242  // if failure, try MODUL_CMD
6243  if (t==0)
6244  {
6245    h=v;
6246    while (h!=NULL)
6247    {
6248      if (iiTestConvert(h->Typ(),MODUL_CMD)!=0)
6249      {
6250        t=MODUL_CMD;
6251      }
6252      else break;
6253      h=h->next;
6254    }
6255  }
6256  // check for success  in converting
6257  if (t==0)
6258  {
6259    WerrorS("cannot convert to ideal or module");
6260    return TRUE;
6261  }
6262  // call idMultSect
6263  h=v;
6264  int i=0;
6265  sleftv tmp;
6266  while (h!=NULL)
6267  {
6268    if (h->Typ()==t)
6269    {
6270      r[i]=(ideal)h->Data(); /*no copy*/
6271      h=h->next;
6272    }
6273    else if(iiConvert(h->Typ(),t,iiTestConvert(h->Typ(),t),h,&tmp))
6274    {
6275      omFreeSize((ADDRESS)copied,l*sizeof(BOOLEAN));
6276      omFreeSize((ADDRESS)r,l*sizeof(ideal));
6277      Werror("cannot convert arg. %d to %s",i+1,Tok2Cmdname(t));
6278      return TRUE;
6279    }
6280    else
6281    {
6282      r[i]=(ideal)tmp.Data(); /*now it's a copy*/
6283      copied[i]=TRUE;
6284      h=tmp.next;
6285    }
6286    i++;
6287  }
6288  res->rtyp=t;
6289  res->data=(char *)idMultSect(r,i);
6290  while(i>0)
6291  {
6292    i--;
6293    if (copied[i]) idDelete(&(r[i]));
6294  }
6295  omFreeSize((ADDRESS)copied,l*sizeof(BOOLEAN));
6296  omFreeSize((ADDRESS)r,l*sizeof(ideal));
6297  return FALSE;
6298}
6299static BOOLEAN jjLU_INVERSE(leftv res, leftv v)
6300{
6301  /* computation of the inverse of a quadratic matrix A
6302     using the L-U-decomposition of A;
6303     There are two valid parametrisations:
6304     1) exactly one argument which is just the matrix A,
6305     2) exactly three arguments P, L, U which already
6306        realise the L-U-decomposition of A, that is,
6307        P * A = L * U, and P, L, and U satisfy the
6308        properties decribed in method 'jjLU_DECOMP';
6309        see there;
6310     If A is invertible, the list [1, A^(-1)] is returned,
6311     otherwise the list [0] is returned. Thus, the user may
6312     inspect the first entry of the returned list to see
6313     whether A is invertible. */
6314  matrix iMat; int invertible;
6315  if (v->next == NULL)
6316  {
6317    if (v->Typ() != MATRIX_CMD)
6318    {
6319      Werror("expected either one or three matrices");
6320      return TRUE;
6321    }
6322    else
6323    {
6324      matrix aMat = (matrix)v->Data();
6325      int rr = aMat->rows();
6326      int cc = aMat->cols();
6327      if (rr != cc)
6328      {
6329        Werror("given matrix (%d x %d) is not quadratic, hence not invertible", rr, cc);
6330        return TRUE;
6331      }
6332      invertible = luInverse(aMat, iMat);
6333    }
6334  }
6335  else if ((v->Typ() == MATRIX_CMD) &&
6336           (v->next->Typ() == MATRIX_CMD) &&
6337           (v->next->next != NULL) &&
6338           (v->next->next->Typ() == MATRIX_CMD) &&
6339           (v->next->next->next == NULL))
6340  {
6341     matrix pMat = (matrix)v->Data();
6342     matrix lMat = (matrix)v->next->Data();
6343     matrix uMat = (matrix)v->next->next->Data();
6344     int rr = uMat->rows();
6345     int cc = uMat->cols();
6346     if (rr != cc)
6347     {
6348       Werror("third matrix (%d x %d) is not quadratic, hence not invertible",
6349              rr, cc);
6350       return TRUE;
6351     }
6352     invertible = luInverseFromLUDecomp(pMat, lMat, uMat, iMat);
6353  }
6354  else
6355  {
6356    Werror("expected either one or three matrices");
6357    return TRUE;
6358  }
6359
6360  /* build the return structure; a list with either one or two entries */
6361  lists ll = (lists)omAllocBin(slists_bin);
6362  if (invertible)
6363  {
6364    ll->Init(2);
6365    ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)invertible;
6366    ll->m[1].rtyp=MATRIX_CMD; ll->m[1].data=(void *)iMat;
6367  }
6368  else
6369  {
6370    ll->Init(1);
6371    ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)invertible;
6372  }
6373
6374  res->data=(char*)ll;
6375  return FALSE;
6376}
6377static BOOLEAN jjLU_SOLVE(leftv res, leftv v)
6378{
6379  /* for solving a linear equation system A * x = b, via the
6380     given LU-decomposition of the matrix A;
6381     There is one valid parametrisation:
6382     1) exactly four arguments P, L, U, b;
6383        P, L, and U realise the L-U-decomposition of A, that is,
6384        P * A = L * U, and P, L, and U satisfy the
6385        properties decribed in method 'jjLU_DECOMP';
6386        see there;
6387        b is the right-hand side vector of the equation system;
6388     The method will return a list of either 1 entry or three entries:
6389     1) [0] if there is no solution to the system;
6390     2) [1, x, H] if there is at least one solution;
6391        x is any solution of the given linear system,
6392        H is the matrix with column vectors spanning the homogeneous
6393        solution space.
6394     The method produces an error if matrix and vector sizes do not fit. */
6395  if ((v == NULL) || (v->Typ() != MATRIX_CMD) ||
6396      (v->next == NULL) || (v->next->Typ() != MATRIX_CMD) ||
6397      (v->next->next == NULL) || (v->next->next->Typ() != MATRIX_CMD) ||
6398      (v->next->next->next == NULL) ||
6399      (v->next->next->next->Typ() != MATRIX_CMD) ||
6400      (v->next->next->next->next != NULL))
6401  {
6402    WerrorS("expected exactly three matrices and one vector as input");
6403    return TRUE;
6404  }
6405  matrix pMat = (matrix)v->Data();
6406  matrix lMat = (matrix)v->next->Data();
6407  matrix uMat = (matrix)v->next->next->Data();
6408  matrix bVec = (matrix)v->next->next->next->Data();
6409  matrix xVec; int solvable; matrix homogSolSpace;
6410  if (pMat->rows() != pMat->cols())
6411  {
6412    Werror("first matrix (%d x %d) is not quadratic",
6413           pMat->rows(), pMat->cols());
6414    return TRUE;
6415  }
6416  if (lMat->rows() != lMat->cols())
6417  {
6418    Werror("second matrix (%d x %d) is not quadratic",
6419           lMat->rows(), lMat->cols());
6420    return TRUE;
6421  }
6422  if (lMat->rows() != uMat->rows())
6423  {
6424    Werror("second matrix (%d x %d) and third matrix (%d x %d) do not fit",
6425           lMat->rows(), lMat->cols(), uMat->rows(), uMat->cols());
6426    return TRUE;
6427  }
6428  if (uMat->rows() != bVec->rows())
6429  {
6430    Werror("third matrix (%d x %d) and vector (%d x 1) do not fit",
6431           uMat->rows(), uMat->cols(), bVec->rows());
6432    return TRUE;
6433  }
6434  solvable = luSolveViaLUDecomp(pMat, lMat, uMat, bVec, xVec, homogSolSpace);
6435
6436  /* build the return structure; a list with either one or three entries */
6437  lists ll = (lists)omAllocBin(slists_bin);
6438  if (solvable)
6439  {
6440    ll->Init(3);
6441    ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)solvable;
6442    ll->m[1].rtyp=MATRIX_CMD; ll->m[1].data=(void *)xVec;
6443    ll->m[2].rtyp=MATRIX_CMD; ll->m[2].data=(void *)homogSolSpace;
6444  }
6445  else
6446  {
6447    ll->Init(1);
6448    ll->m[0].rtyp=INT_CMD;    ll->m[0].data=(void *)solvable;
6449  }
6450
6451  res->data=(char*)ll;
6452  return FALSE;
6453}
6454static BOOLEAN jjINTVEC_PL(leftv res, leftv v)
6455{
6456  int i=0;
6457  leftv h=v;
6458  if (h!=NULL) i=exprlist_length(h);
6459  intvec *iv=new intvec(i);
6460  i=0;
6461  while (h!=NULL)
6462  {
6463    if(h->Typ()==INT_CMD)
6464    {
6465      (*iv)[i]=(int)(long)h->Data();
6466    }
6467    else
6468    {
6469      delete iv;
6470      return TRUE;
6471    }
6472    i++;
6473    h=h->next;
6474  }
6475  res->data=(char *)iv;
6476  return FALSE;
6477}
6478static BOOLEAN jjJET4(leftv res, leftv u)
6479{
6480  leftv u1=u;
6481  leftv u2=u1->next;
6482  leftv u3=u2->next;
6483  leftv u4=u3->next;
6484  if((u2->Typ()==POLY_CMD)&&(u3->Typ()==INT_CMD)&&(u4->Typ()==INTVEC_CMD)
6485  &&((u1->Typ()==POLY_CMD)||(u1->Typ()==VECTOR_CMD)))
6486  {
6487    if(!pIsUnit((poly)u2->Data()))
6488    {
6489      WerrorS("2nd argument must be a unit");
6490      return TRUE;
6491    }
6492    res->rtyp=u1->Typ();
6493    res->data=(char*)pSeries((int)(long)u3->Data(),pCopy((poly)u1->Data()),
6494                             pCopy((poly)u2->Data()),(intvec*)u4->Data());
6495    return FALSE;
6496  }
6497  else
6498  if((u2->Typ()==MATRIX_CMD)&&(u3->Typ()==INT_CMD)&&(u4->Typ()==INTVEC_CMD)
6499  &&((u1->Typ()==IDEAL_CMD)||(u1->Typ()==MODUL_CMD)))
6500  {
6501    if(!mpIsDiagUnit((matrix)u2->Data()))
6502    {
6503      WerrorS("2nd argument must be a diagonal matrix of units");
6504      return TRUE;
6505    }
6506    res->rtyp=u1->Typ();
6507    res->data=(char*)idSeries((int)(long)u3->Data(),idCopy((ideal)u1->Data()),
6508                              mpCopy((matrix)u2->Data()),(intvec*)u4->Data());
6509    return FALSE;
6510  }
6511  else
6512  {
6513    Werror("%s(`poly`,`poly`,`int`,`intvec`) exppected",
6514           Tok2Cmdname(iiOp));
6515    return TRUE;
6516  }
6517}
6518static BOOLEAN jjKLAMMER_PL(leftv res, leftv u)
6519{
6520  if ((yyInRingConstruction)
6521  && ((strcmp(u->Name(),"real")==0) || (strcmp(u->Name(),"complex")==0)))
6522  {
6523    memcpy(res,u,sizeof(sleftv));
6524    memset(u,0,sizeof(sleftv));
6525    return FALSE;
6526  }
6527  leftv v=u->next;
6528  BOOLEAN b;
6529  if(v==NULL)
6530    b=iiExprArith1(res,u,iiOp);
6531  else
6532  {
6533    u->next=NULL;
6534    b=iiExprArith2(res,u,iiOp,v);
6535    u->next=v;
6536  }
6537  return b;
6538}
6539static BOOLEAN jjLIST_PL(leftv res, leftv v)
6540{
6541  int sl=0;
6542  if (v!=NULL) sl = v->listLength();
6543  lists L;
6544  if((sl==1)&&(v->Typ()==RESOLUTION_CMD))
6545  {
6546    int add_row_shift = 0;
6547    intvec *weights=(intvec*)atGet(v,"isHomog",INTVEC_CMD);
6548    if (weights!=NULL)  add_row_shift=weights->min_in();
6549    L=syConvRes((syStrategy)v->Data(),FALSE,add_row_shift);
6550  }
6551  else
6552  {
6553    L=(lists)omAllocBin(slists_bin);
6554    leftv h=NULL;
6555    int i;
6556    int rt;
6557
6558    L->Init(sl);
6559    for (i=0;i<sl;i++)
6560    {
6561      if (h!=NULL)
6562      { /* e.g. not in the first step:
6563         * h is the pointer to the old sleftv,
6564         * v is the pointer to the next sleftv
6565         * (in this moment) */
6566         h->next=v;
6567      }
6568      h=v;
6569      v=v->next;
6570      h->next=NULL;
6571      rt=h->Typ();
6572      if (rt==0)
6573      {
6574        L->Clean();
6575        Werror("`%s` is undefined",h->Fullname());
6576        return TRUE;
6577      }
6578      if ((rt==RING_CMD)||(rt==QRING_CMD))
6579      {
6580        L->m[i].rtyp=rt;  L->m[i].data=h->Data();
6581        ((ring)L->m[i].data)->ref++;
6582      }
6583      else
6584        L->m[i].Copy(h);
6585    }
6586  }
6587  res->data=(char *)L;
6588  return FALSE;
6589}
6590static BOOLEAN jjNAMES0(leftv res, leftv v)
6591{
6592  res->data=(void *)ipNameList(IDROOT);
6593  return FALSE;
6594}
6595static BOOLEAN jjOPTION_PL(leftv res, leftv v)
6596{
6597  if(v==NULL)
6598  {
6599    res->data=(char *)showOption();
6600    return FALSE;
6601  }
6602  res->rtyp=NONE;
6603  return setOption(res,v);
6604}
6605static BOOLEAN jjREDUCE4(leftv res, leftv u)
6606{
6607  leftv u1=u;
6608  leftv u2=u1->next;
6609  leftv u3=u2->next;
6610  leftv u4=u3->next;
6611  if((u3->Typ()==INT_CMD)&&(u4->Typ()==INTVEC_CMD))
6612  {
6613    int save_d=Kstd1_deg;
6614    Kstd1_deg=(int)(long)u3->Data();
6615    kModW=(intvec *)u4->Data();
6616    BITSET save=verbose;
6617    verbose|=Sy_bit(V_DEG_STOP);
6618    u2->next=NULL;
6619    BOOLEAN r=jjCALL2ARG(res,u);
6620    kModW=NULL;
6621    Kstd1_deg=save_d;
6622    verbose=save;
6623    u->next->next=u3;
6624    return r;
6625  }
6626  else
6627  if((u1->Typ()==IDEAL_CMD)&&(u2->Typ()==MATRIX_CMD)&&(u3->Typ()==IDEAL_CMD)&&
6628     (u4->Typ()==INT_CMD))
6629  {
6630    assumeStdFlag(u3);
6631    if(!mpIsDiagUnit((matrix)u2->Data()))
6632    {
6633      WerrorS("2nd argument must be a diagonal matrix of units");
6634      return TRUE;
6635    }
6636    res->rtyp=IDEAL_CMD;
6637    res->data=(char*)redNF(idCopy((ideal)u3->Data()),idCopy((ideal)u1->Data()),
6638                           mpCopy((matrix)u2->Data()),(int)(long)u4->Data());
6639    return FALSE;
6640  }
6641  else
6642  if((u1->Typ()==POLY_CMD)&&(u2->Typ()==POLY_CMD)&&(u3->Typ()==IDEAL_CMD)&&
6643     (u4->Typ()==INT_CMD))
6644  {
6645    assumeStdFlag(u3);
6646    if(!pIsUnit((poly)u2->Data()))
6647    {
6648      WerrorS("2nd argument must be a unit");
6649      return TRUE;
6650    }
6651    res->rtyp=POLY_CMD;
6652    res->data=(char*)redNF(idCopy((ideal)u3->Data()),pCopy((poly)u1->Data()),
6653                           pCopy((poly)u2->Data()),(int)(long)u4->Data());
6654    return FALSE;
6655  }
6656  else
6657  {
6658    Werror("%s(`poly`,`ideal`,`int`,`intvec`) expected",Tok2Cmdname(iiOp));
6659    return TRUE;
6660  }
6661}
6662static BOOLEAN jjREDUCE5(leftv res, leftv u)
6663{
6664  leftv u1=u;
6665  leftv u2=u1->next;
6666  leftv u3=u2->next;
6667  leftv u4=u3->next;
6668  leftv u5=u4->next;
6669  if((u1->Typ()==IDEAL_CMD)&&(u2->Typ()==MATRIX_CMD)&&(u3->Typ()==IDEAL_CMD)&&
6670     (u4->Typ()==INT_CMD)&&(u5->Typ()==INTVEC_CMD))
6671  {
6672    assumeStdFlag(u3);
6673    if(!mpIsDiagUnit((matrix)u2->Data()))
6674    {
6675      WerrorS("2nd argument must be a diagonal matrix of units");
6676      return TRUE;
6677    }
6678    res->rtyp=IDEAL_CMD;
6679    res->data=(char*)redNF(idCopy((ideal)u3->Data()),idCopy((ideal)u1->Data()),
6680                           mpCopy((matrix)u2->Data()),
6681                           (int)(long)u4->Data(),(intvec*)u5->Data());
6682    return FALSE;
6683  }
6684  else
6685  if((u1->Typ()==POLY_CMD)&&(u2->Typ()==POLY_CMD)&&(u3->Typ()==IDEAL_CMD)&&
6686     (u4->Typ()==INT_CMD)&&(u5->Typ()==INTVEC_CMD))
6687  {
6688    assumeStdFlag(u3);
6689    if(!pIsUnit((poly)u2->Data()))
6690    {
6691      WerrorS("2nd argument must be a unit");
6692      return TRUE;
6693    }
6694    res->rtyp=POLY_CMD;
6695    res->data=(char*)redNF(idCopy((ideal)u3->Data()),pCopy((poly)u1->Data()),
6696                           pCopy((poly)u2->Data()),
6697                           (int)(long)u4->Data(),(intvec*)u5->Data());
6698    return FALSE;
6699  }
6700  else
6701  {
6702    Werror("%s(`ideal`,`ideal`,`matrix`,`int`,`intvec`) exppected",
6703           Tok2Cmdname(iiOp));
6704    return TRUE;
6705  }
6706}
6707static BOOLEAN jjRESERVED0(leftv res, leftv v)
6708{
6709  int i=1;
6710  int nCount = (sArithBase.nCmdUsed-1)/3;
6711  if((3*nCount)<sArithBase.nCmdUsed) nCount++;
6712  //Print("CMDS: %d/%d\n", sArithBase.nCmdUsed,
6713  //      sArithBase.nCmdAllocated);
6714  for(i=0; i<nCount; i++)
6715  {
6716    Print("%-20s",sArithBase.sCmds[i+1].name);
6717    if(i+1+nCount<sArithBase.nCmdUsed)
6718      Print("%-20s",sArithBase.sCmds[i+1+nCount].name);
6719    if(i+1+2*nCount<sArithBase.nCmdUsed)
6720      Print("%-20s",sArithBase.sCmds[i+1+2*nCount].name);
6721    //if ((i%3)==1) PrintLn();
6722    PrintLn();
6723  }
6724  PrintLn();
6725  printBlackboxTypes();
6726  return FALSE;
6727}
6728static BOOLEAN jjSTRING_PL(leftv res, leftv v)
6729{
6730  if (v == NULL)
6731  {
6732    res->data = omStrDup("");
6733    return FALSE;
6734  }
6735  int n = v->listLength();
6736  if (n == 1)
6737  {
6738    res->data = v->String();
6739    return FALSE;
6740  }
6741
6742  char** slist = (char**) omAlloc(n*sizeof(char*));
6743  int i, j;
6744
6745  for (i=0, j=0; i<n; i++, v = v ->next)
6746  {
6747    slist[i] = v->String();
6748    assume(slist[i] != NULL);
6749    j+=strlen(slist[i]);
6750  }
6751  char* s = (char*) omAlloc((j+1)*sizeof(char));
6752  *s='\0';
6753  for (i=0;i<n;i++)
6754  {
6755    strcat(s, slist[i]);
6756    omFree(slist[i]);
6757  }
6758  omFreeSize(slist, n*sizeof(char*));
6759  res->data = s;
6760  return FALSE;
6761}
6762static BOOLEAN jjTEST(leftv res, leftv v)
6763{
6764  do
6765  {
6766    if (v->Typ()!=INT_CMD)
6767      return TRUE;
6768    test_cmd((int)(long)v->Data());
6769    v=v->next;
6770  }
6771  while (v!=NULL);
6772  return FALSE;
6773}
6774
6775#if defined(__alpha) && !defined(linux)
6776extern "C"
6777{
6778  void usleep(unsigned long usec);
6779};
6780#endif
6781static BOOLEAN jjFactModD_M(leftv res, leftv v)
6782{
6783  /* compute two factors of h(x,y) modulo x^(d+1) in K[[x]][y],
6784     see a detailed documentation in /kernel/linearAlgebra.h
6785     
6786     valid argument lists:
6787     - (poly h, int d),
6788     - (poly h, int d, poly f0, poly g0),       optional: factors of h(0,y),
6789     - (poly h, int d, int xIndex, int yIndex), optional: indices of vars x & y
6790                                                          in list of ring vars,
6791     - (poly h, int d, poly f0, poly g0, int xIndex, int yIndec),
6792                                                optional: all 4 optional args
6793     (The defaults are xIndex = 1, yIndex = 2, f0 and g0 polynomials as found
6794      by singclap_factorize in the case that HAVE_FACTORY is defined and h(0, y)
6795      has exactly two distinct monic factors [possibly with exponent > 1].)
6796     result:
6797     - list with the two factors f and g such that
6798       h(x,y) = f(x,y)*g(x,y) mod x^(d+1)   */
6799 
6800  poly h      = NULL;
6801  int  d      =    1;
6802  poly f0     = NULL;
6803  poly g0     = NULL;
6804  int  xIndex =    1;   /* default index if none provided */
6805  int  yIndex =    2;   /* default index if none provided */
6806 
6807  leftv u = v; int factorsGiven = 0;
6808  if ((u == NULL) || (u->Typ() != POLY_CMD))
6809  {
6810    WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
6811    return TRUE;
6812  }
6813  else h = (poly)u->Data();
6814  u = u->next;
6815  if ((u == NULL) || (u->Typ() != INT_CMD))
6816  {
6817    WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
6818    return TRUE;
6819  }
6820  else d = (int)(long)u->Data();
6821  u = u->next;
6822  if ((u != NULL) && (u->Typ() == POLY_CMD))
6823  {
6824    if ((u->next == NULL) || (u->next->Typ() != POLY_CMD))
6825    {
6826      WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
6827      return TRUE;
6828    }
6829    else
6830    {
6831      f0 = (poly)u->Data();
6832      g0 = (poly)u->next->Data();
6833      factorsGiven = 1;
6834      u = u->next->next;
6835    }
6836  }
6837  if ((u != NULL) && (u->Typ() == INT_CMD))
6838  {
6839    if ((u->next == NULL) || (u->next->Typ() != INT_CMD))
6840    {
6841      WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
6842      return TRUE;
6843    }
6844    else
6845    {
6846      xIndex = (int)(long)u->Data();
6847      yIndex = (int)(long)u->next->Data();
6848      u = u->next->next;
6849    }
6850  }
6851  if (u != NULL)
6852  {
6853    WerrorS("expected arguments (poly, int [, poly, poly] [, int, int])");
6854    return TRUE;
6855  }
6856 
6857  /* checks for provided arguments */
6858  if (pIsConstant(h) || (factorsGiven && (pIsConstant(f0) || pIsConstant(g0))))
6859  {
6860    WerrorS("expected non-constant polynomial argument(s)");
6861    return TRUE;
6862  }
6863  int n = rVar(currRing);
6864  if ((xIndex < 1) || (n < xIndex))
6865  {
6866    Werror("index for variable x (%d) out of range [1..%d]", xIndex, n);
6867    return TRUE;
6868  }
6869  if ((yIndex < 1) || (n < yIndex))
6870  {
6871    Werror("index for variable y (%d) out of range [1..%d]", yIndex, n);
6872    return TRUE;
6873  }
6874  if (xIndex == yIndex)
6875  {
6876    WerrorS("expected distinct indices for variables x and y");
6877    return TRUE;
6878  }
6879 
6880  /* computation of f0 and g0 if missing */
6881  if (factorsGiven == 0)
6882  {
6883#ifdef HAVE_FACTORY
6884    poly h0 = pSubst(pCopy(h), xIndex, NULL);
6885    intvec* v = NULL;
6886    ideal i = singclap_factorize(h0, &v, 0);
6887
6888    ivTest(v);
6889
6890    if (i == NULL) return TRUE;
6891
6892    idTest(i);
6893   
6894    if ((v->rows() != 3) || ((*v)[0] =! 1) || (!nIsOne(pGetCoeff(i->m[0]))))
6895    {
6896      WerrorS("expected h(0,y) to have exactly two distinct monic factors");
6897      return TRUE;
6898    }
6899    f0 = pPower(pCopy(i->m[1]), (*v)[1]);
6900    g0 = pPower(pCopy(i->m[2]), (*v)[2]);
6901    idDelete(&i);
6902#else
6903    WerrorS("cannot factorize h(0,y) due to missing module 'factory'");
6904    return TRUE;
6905#endif
6906  }
6907 
6908  poly f; poly g;
6909  henselFactors(xIndex, yIndex, h, f0, g0, d, f, g);
6910  lists L = (lists)omAllocBin(slists_bin);
6911  L->Init(2);
6912  L->m[0].rtyp = POLY_CMD; L->m[0].data=(void*)f;
6913  L->m[1].rtyp = POLY_CMD; L->m[1].data=(void*)g;
6914  res->rtyp = LIST_CMD;
6915  res->data = (char*)L;
6916  return FALSE;
6917}
6918static BOOLEAN jjSTATUS_M(leftv res, leftv v)
6919{
6920  if ((v->Typ() != LINK_CMD) ||
6921      (v->next->Typ() != STRING_CMD) ||
6922      (v->next->next->Typ() != STRING_CMD) ||
6923      (v->next->next->next->Typ() != INT_CMD))
6924    return TRUE;
6925  jjSTATUS3(res, v, v->next, v->next->next);
6926#if defined(HAVE_USLEEP)
6927  if (((long) res->data) == 0L)
6928  {
6929    int i_s = (int)(long) v->next->next->next->Data();
6930    if (i_s > 0)
6931    {
6932      usleep((int)(long) v->next->next->next->Data());
6933      jjSTATUS3(res, v, v->next, v->next->next);
6934    }
6935  }
6936#elif defined(HAVE_SLEEP)
6937  if (((int) res->data) == 0)
6938  {
6939    int i_s = (int) v->next->next->next->Data();
6940    if (i_s > 0)
6941    {
6942      sleep((is - 1)/1000000 + 1);
6943      jjSTATUS3(res, v, v->next, v->next->next);
6944    }
6945  }
6946#endif
6947  return FALSE;
6948}
6949static BOOLEAN jjSUBST_M(leftv res, leftv u)
6950{
6951  leftv v = u->next; // number of args > 0
6952  if (v==NULL) return TRUE;
6953  leftv w = v->next;
6954  if (w==NULL) return TRUE;
6955  leftv rest = w->next;;
6956
6957  u->next = NULL;
6958  v->next = NULL;
6959  w->next = NULL;
6960  BOOLEAN b = iiExprArith3(res, iiOp, u, v, w);
6961  if ((rest!=NULL) && (!b))
6962  {
6963    sleftv tmp_res;
6964    leftv tmp_next=res->next;
6965    res->next=rest;
6966    memset(&tmp_res,0,sizeof(tmp_res));
6967    b = iiExprArithM(&tmp_res,res,iiOp);
6968    memcpy(res,&tmp_res,sizeof(tmp_res));
6969    res->next=tmp_next;
6970  }
6971  u->next = v;
6972  v->next = w;
6973  // rest was w->next, but is already cleaned
6974  return b;
6975}
6976static BOOLEAN jjQRDS(leftv res, leftv INPUT)
6977{
6978  if ((INPUT->Typ() != MATRIX_CMD) ||
6979      (INPUT->next->Typ() != NUMBER_CMD) ||
6980      (INPUT->next->next->Typ() != NUMBER_CMD) ||
6981      (INPUT->next->next->next->Typ() != NUMBER_CMD))
6982  {
6983    WerrorS("expected (matrix, number, number, number) as arguments");
6984    return TRUE;
6985  }
6986  leftv u = INPUT; leftv v = u->next; leftv w = v->next; leftv x = w->next;
6987  res->data = (char *)qrDoubleShift((matrix)(u->Data()),
6988                                    (number)(v->Data()),
6989                                    (number)(w->Data()),
6990                                    (number)(x->Data()));
6991  return FALSE;
6992}
6993static BOOLEAN jjSTD_HILB_WP(leftv res, leftv INPUT)
6994{ ideal result;
6995  leftv u = INPUT;    /* an ideal, weighted homogeneous and standard */
6996  leftv v = u->next;  /* one additional polynomial or ideal */
6997  leftv h = v->next;  /* Hilbert vector */
6998  leftv w = h->next;  /* weight vector */
6999  assumeStdFlag(u);
7000  ideal i1=(ideal)(u->Data());
7001  ideal i0;
7002  if (((u->Typ()!=IDEAL_CMD)&&(u->Typ()!=MODUL_CMD))
7003  || (h->Typ()!=INTVEC_CMD)
7004  || (w->Typ()!=INTVEC_CMD))
7005  {
7006    WerrorS("expected `std(`ideal/module`,`poly/vector`,`intvec`,`intvec`)");
7007    return TRUE;
7008  }
7009  intvec *vw=(intvec *)w->Data(); // weights of vars
7010  /* merging std_hilb_w and std_1 */
7011  if (vw->length()!=currRing->N)
7012  {
7013    Werror("%d weights for %d variables",vw->length(),currRing->N);
7014    return TRUE;
7015  }
7016  int r=v->Typ();
7017  BOOLEAN cleanup_i0=FALSE;
7018  if ((r==POLY_CMD) ||(r==VECTOR_CMD))
7019  {
7020    i0=idInit(1,i1->rank);
7021    i0->m[0]=(poly)v->Data();
7022    BOOLEAN cleanup_i0=TRUE;
7023  }
7024  else if (r==IDEAL_CMD)/* IDEAL */
7025  {
7026    i0=(ideal)v->Data();
7027  }
7028  else
7029  {
7030    WerrorS("expected `std(`ideal/module`,`poly/vector`,`intvec`,`intvec`)");
7031    return TRUE;
7032  }
7033  int ii0=idElem(i0);
7034  i1 = idSimpleAdd(i1,i0);
7035  if (cleanup_i0)
7036  {
7037    memset(i0->m,0,sizeof(poly)*IDELEMS(i0));
7038    idDelete(&i0);
7039  }
7040  intvec *ww=(intvec *)atGet(u,"isHomog",INTVEC_CMD);
7041  tHomog hom=testHomog;
7042  /* u_id from jjSTD_W is now i1 as in jjSTD_1 */
7043  if (ww!=NULL)
7044  {
7045    if (!idTestHomModule(i1,currQuotient,ww))
7046    {
7047      WarnS("wrong weights");
7048      ww=NULL;
7049    }
7050    else
7051    {
7052      ww=ivCopy(ww);
7053      hom=isHomog;
7054    }
7055  }
7056  BITSET save_test=test;
7057  test|=Sy_bit(OPT_SB_1);
7058  result=kStd(i1,
7059              currQuotient,
7060              hom,
7061              &ww,                  // module weights
7062              (intvec *)h->Data(),  // hilbert series
7063              0,                    // syzComp, whatever it is...
7064              IDELEMS(i1)-ii0,      // new ideal
7065              vw);                  // weights of vars
7066  test=save_test;
7067  idDelete(&i1);
7068  idSkipZeroes(result);
7069  res->data = (char *)result;
7070  if (!TEST_OPT_DEGBOUND) setFlag(res,FLAG_STD);
7071  if (ww!=NULL) atSet(res,omStrDup("isHomog"),ww,INTVEC_CMD);
7072  return FALSE;
7073}
7074
7075
7076#ifdef MDEBUG
7077static Subexpr jjDBMakeSub(leftv e,const char *f,const int l)
7078#else
7079static Subexpr jjMakeSub(leftv e)
7080#endif
7081{
7082  assume( e->Typ()==INT_CMD );
7083  Subexpr r=(Subexpr)omAlloc0Bin(sSubexpr_bin);
7084  r->start =(int)(long)e->Data();
7085  return r;
7086}
7087#define D(A) (A)
7088#define IPARITH
7089#include "table.h"
7090
7091#include <iparith.inc>
7092
7093/*=================== operations with 2 args. ============================*/
7094/* must be ordered: first operations for chars (infix ops),
7095 * then alphabetically */
7096
7097BOOLEAN iiExprArith2(leftv res, leftv a, int op, leftv b, BOOLEAN proccall)
7098{
7099  memset(res,0,sizeof(sleftv));
7100  BOOLEAN call_failed=FALSE;
7101
7102  if (!errorreported)
7103  {
7104#ifdef SIQ
7105    if (siq>0)
7106    {
7107      //Print("siq:%d\n",siq);
7108      command d=(command)omAlloc0Bin(sip_command_bin);
7109      memcpy(&d->arg1,a,sizeof(sleftv));
7110      //a->Init();
7111      memcpy(&d->arg2,b,sizeof(sleftv));
7112      //b->Init();
7113      d->argc=2;
7114      d->op=op;
7115      res->data=(char *)d;
7116      res->rtyp=COMMAND;
7117      return FALSE;
7118    }
7119#endif
7120    int at=a->Typ();
7121    if (at>MAX_TOK)
7122    {
7123      blackbox *bb=getBlackboxStuff(at);
7124      if (bb!=NULL) return bb->blackbox_Op2(op,res,a,b);
7125      else          return TRUE;
7126    }
7127    int bt=b->Typ();
7128    int i=iiTabIndex(dArithTab2,JJTAB2LEN,op);
7129    int index=i;
7130
7131    iiOp=op;
7132    while (dArith2[i].cmd==op)
7133    {
7134      if ((at==dArith2[i].arg1)
7135      && (bt==dArith2[i].arg2))
7136      {
7137        res->rtyp=dArith2[i].res;
7138        if (currRing!=NULL)
7139        {
7140          #ifdef HAVE_PLURAL
7141          if (rIsPluralRing(currRing))
7142          {
7143            if ((dArith2[i].valid_for & PLURAL_MASK)==0 /*NO_PLURAL*/)
7144            {
7145              WerrorS(ii_not_for_plural);
7146              break;
7147            }
7148            else if ((dArith2[i].valid_for & PLURAL_MASK)==2 /*, COMM_PLURAL */)
7149            {
7150              Warn("assume commutative subalgebra for cmd `%s`",Tok2Cmdname(i));
7151            }
7152            /* else, ALLOW_PLURAL */
7153          }
7154          #endif
7155          #ifdef HAVE_RINGS
7156          if (rField_is_Ring(currRing))
7157          {
7158            if ((dArith2[i].valid_for & RING_MASK)==0 /*NO_RING*/)
7159            {
7160              WerrorS(ii_not_for_ring);
7161              break;
7162            }
7163            /* else ALLOW_RING */
7164          }
7165          #endif
7166        }
7167        if (TEST_V_ALLWARN)
7168          Print("call %s(%s,%s)\n",Tok2Cmdname(iiOp),Tok2Cmdname(at),Tok2Cmdname(bt));
7169        if ((call_failed=dArith2[i].p(res,a,b)))
7170        {
7171          break;// leave loop, goto error handling
7172        }
7173        a->CleanUp();
7174        b->CleanUp();
7175        //Print("op: %d,result typ:%d\n",op,res->rtyp);
7176        return FALSE;
7177      }
7178      i++;
7179    }
7180    // implicite type conversion ----------------------------------------------
7181    if (dArith2[i].cmd!=op)
7182    {
7183      int ai,bi;
7184      leftv an = (leftv)omAlloc0Bin(sleftv_bin);
7185      leftv bn = (leftv)omAlloc0Bin(sleftv_bin);
7186      BOOLEAN failed=FALSE;
7187      i=index; /*iiTabIndex(dArithTab2,JJTAB2LEN,op);*/
7188      //Print("op: %c, type: %s %s\n",op,Tok2Cmdname(at),Tok2Cmdname(bt));
7189      while (dArith2[i].cmd==op)
7190      {
7191        //Print("test %s %s\n",Tok2Cmdname(dArith2[i].arg1),Tok2Cmdname(dArith2[i].arg2));
7192        if ((ai=iiTestConvert(at,dArith2[i].arg1))!=0)
7193        {
7194          if ((bi=iiTestConvert(bt,dArith2[i].arg2))!=0)
7195          {
7196            res->rtyp=dArith2[i].res;
7197            if (currRing!=NULL)
7198            {
7199              #ifdef HAVE_PLURAL
7200              if (rIsPluralRing(currRing))
7201              {
7202                if ((dArith2[i].valid_for & PLURAL_MASK)==0 /*NO_PLURAL*/)
7203                {
7204                  WerrorS(ii_not_for_plural);
7205                  break;
7206                }
7207                else if ((dArith2[i].valid_for &PLURAL_MASK)==2 /*, COMM_PLURAL */)
7208                {
7209                  Warn("assume commutative subalgebra for cmd `%s`",
7210                        Tok2Cmdname(i));
7211                }
7212                /* else, ALLOW_PLURAL */
7213              }
7214              #endif
7215              #ifdef HAVE_RINGS
7216              if (rField_is_Ring(currRing))
7217              {
7218                if ((dArith2[i].valid_for & RING_MASK)==0 /*NO_RING*/)
7219                {
7220                  WerrorS(ii_not_for_ring);
7221                  break;
7222                }
7223                /* else ALLOW_RING */
7224              }
7225              #endif
7226            }
7227            if (TEST_V_ALLWARN)
7228              Print("call %s(%s,%s)\n",Tok2Cmdname(iiOp),
7229              Tok2Cmdname(an->rtyp),Tok2Cmdname(bn->rtyp));
7230            failed= ((iiConvert(at,dArith2[i].arg1,ai,a,an))
7231            || (iiConvert(bt,dArith2[i].arg2,bi,b,bn))
7232            || (call_failed=dArith2[i].p(res,an,bn)));
7233            // everything done, clean up temp. variables
7234            if (failed)
7235            {
7236              // leave loop, goto error handling
7237              break;
7238            }
7239            else
7240            {
7241              // everything ok, clean up and return
7242              an->CleanUp();
7243              bn->CleanUp();
7244              omFreeBin((ADDRESS)an, sleftv_bin);
7245              omFreeBin((ADDRESS)bn, sleftv_bin);
7246              a->CleanUp();
7247              b->CleanUp();
7248              return FALSE;
7249            }
7250          }
7251        }
7252        i++;
7253      }
7254      an->CleanUp();
7255      bn->CleanUp();
7256      omFreeBin((ADDRESS)an, sleftv_bin);
7257      omFreeBin((ADDRESS)bn, sleftv_bin);
7258    }
7259    // error handling ---------------------------------------------------
7260    const char *s=NULL;
7261    if (!errorreported)
7262    {
7263      if ((at==0) && (a->Fullname()!=sNoName))
7264      {
7265        s=a->Fullname();
7266      }
7267      else if ((bt==0) && (b->Fullname()!=sNoName))
7268      {
7269        s=b->Fullname();
7270      }
7271      if (s!=NULL)
7272        Werror("`%s` is not defined",s);
7273      else
7274      {
7275        i=index; /*iiTabIndex(dArithTab2,JJTAB2LEN,op);*/
7276        s = iiTwoOps(op);
7277        if (proccall)
7278        {
7279          Werror("%s(`%s`,`%s`) failed"
7280                ,s,Tok2Cmdname(at),Tok2Cmdname(bt));
7281        }
7282        else
7283        {
7284          Werror("`%s` %s `%s` failed"
7285                ,Tok2Cmdname(at),s,Tok2Cmdname(bt));
7286        }
7287        if ((!call_failed) && BVERBOSE(V_SHOW_USE))
7288        {
7289          while (dArith2[i].cmd==op)
7290          {
7291            if(((at==dArith2[i].arg1)||(bt==dArith2[i].arg2))
7292            && (dArith2[i].res!=0)
7293            && (dArith2[i].p!=jjWRONG2))
7294            {
7295              if (proccall)
7296                Werror("expected %s(`%s`,`%s`)"
7297                  ,s,Tok2Cmdname(dArith2[i].arg1),Tok2Cmdname(dArith2[i].arg2));
7298              else
7299                Werror("expected `%s` %s `%s`"
7300                  ,Tok2Cmdname(dArith2[i].arg1),s,Tok2Cmdname(dArith2[i].arg2));
7301            }
7302            i++;
7303          }
7304        }
7305      }
7306    }
7307    res->rtyp = UNKNOWN;
7308  }
7309  a->CleanUp();
7310  b->CleanUp();
7311  return TRUE;
7312}
7313
7314/*==================== operations with 1 arg. ===============================*/
7315/* must be ordered: first operations for chars (infix ops),
7316 * then alphabetically */
7317
7318BOOLEAN iiExprArith1(leftv res, leftv a, int op)
7319{
7320  memset(res,0,sizeof(sleftv));
7321  BOOLEAN call_failed=FALSE;
7322
7323  if (!errorreported)
7324  {
7325#ifdef SIQ
7326    if (siq>0)
7327    {
7328      //Print("siq:%d\n",siq);
7329      command d=(command)omAlloc0Bin(sip_command_bin);
7330      memcpy(&d->arg1,a,sizeof(sleftv));
7331      //a->Init();
7332      d->op=op;
7333      d->argc=1;
7334      res->data=(char *)d;
7335      res->rtyp=COMMAND;
7336      return FALSE;
7337    }
7338#endif
7339    int at=a->Typ();
7340    if (at>MAX_TOK)
7341    {
7342      blackbox *bb=getBlackboxStuff(at);
7343      if (bb!=NULL) return bb->blackbox_Op1(op,res,a);
7344      else          return TRUE;
7345    }
7346
7347    BOOLEAN failed=FALSE;
7348    iiOp=op;
7349    int i=iiTabIndex(dArithTab1,JJTAB1LEN,op);
7350    int ti = i;
7351    while (dArith1[i].cmd==op)
7352    {
7353      if (at==dArith1[i].arg)
7354      {
7355        int r=res->rtyp=dArith1[i].res;
7356        if (currRing!=NULL)
7357        {
7358          #ifdef HAVE_PLURAL
7359          if ((currRing!=NULL) && (rIsPluralRing(currRing)))
7360          {
7361            if ((dArith1[i].valid_for &PLURAL_MASK)==0 /*NO_PLURAL*/)
7362            {
7363              WerrorS(ii_not_for_plural);
7364              break;
7365            }
7366            else if ((dArith1[i].valid_for &PLURAL_MASK)==2 /*, COMM_PLURAL */)
7367            {
7368              Warn("assume commutative subalgebra for cmd `%s`",Tok2Cmdname(i));
7369            }
7370            /* else, ALLOW_PLURAL */
7371          }
7372          #endif
7373          #ifdef HAVE_RINGS
7374          if (rField_is_Ring(currRing))
7375          {
7376            if ((dArith1[i].valid_for & RING_MASK)==0 /*NO_RING*/)
7377            {
7378              WerrorS(ii_not_for_ring);
7379              break;
7380            }
7381            /* else ALLOW_RING */
7382          }
7383          #endif
7384        }
7385        if (TEST_V_ALLWARN)
7386          Print("call %s(%s)\n",Tok2Cmdname(iiOp),Tok2Cmdname(at));
7387        if (r<0)
7388        {
7389          res->rtyp=-r;
7390          #ifdef PROC_BUG
7391          dArith1[i].p(res,a);
7392          #else
7393          res->data=(char *)((Proc1)dArith1[i].p)((char *)a->Data());
7394          #endif
7395        }
7396        else if ((call_failed=dArith1[i].p(res,a)))
7397        {
7398          break;// leave loop, goto error handling
7399        }
7400        if (a->Next()!=NULL)
7401        {
7402          res->next=(leftv)omAllocBin(sleftv_bin);
7403          failed=iiExprArith1(res->next,a->next,op);
7404        }
7405        a->CleanUp();
7406        return failed;
7407      }
7408      i++;
7409    }
7410    // implicite type conversion --------------------------------------------
7411    if (dArith1[i].cmd!=op)
7412    {
7413      leftv an = (leftv)omAlloc0Bin(sleftv_bin);
7414      i=ti;
7415      //Print("fuer %c , typ: %s\n",op,Tok2Cmdname(at));
7416      while (dArith1[i].cmd==op)
7417      {
7418        int ai;
7419        //Print("test %s\n",Tok2Cmdname(dArith1[i].arg));
7420        if ((ai=iiTestConvert(at,dArith1[i].arg))!=0)
7421        {
7422          int r=res->rtyp=dArith1[i].res;
7423          #ifdef HAVE_PLURAL
7424          if ((currRing!=NULL) && (rIsPluralRing(currRing)))
7425          {
7426            if ((dArith1[i].valid_for &PLURAL_MASK)==0 /*NO_PLURAL*/)
7427            {
7428              WerrorS(ii_not_for_plural);
7429              break;
7430            }
7431            else if ((dArith1[i].valid_for &PLURAL_MASK)==2 /*, COMM_PLURAL */)
7432            {
7433              Warn("assume commutative subalgebra for cmd `%s`",Tok2Cmdname(i));
7434            }
7435            /* else, ALLOW_PLURAL */
7436          }
7437          #endif
7438          if (r<0)
7439          {
7440            res->rtyp=-r;
7441            failed= iiConvert(at,dArith1[i].arg,ai,a,an);
7442            if (!failed)
7443            {
7444              #ifdef PROC_BUG
7445              dArith1[i].p(res,a);
7446              #else
7447              res->data=(char *)((Proc1)dArith1[i].p)((char *)an->Data());
7448              #endif
7449            }
7450          }
7451          else
7452          {
7453            failed= ((iiConvert(at,dArith1[i].arg,ai,a,an))
7454            || (call_failed=dArith1[i].p(res,an)));
7455          }
7456          // everything done, clean up temp. variables
7457          if (failed)
7458          {
7459            // leave loop, goto error handling
7460            break;
7461          }
7462          else
7463          {
7464            if (TEST_V_ALLWARN)
7465              Print("call %s(%s)\n",Tok2Cmdname(iiOp),Tok2Cmdname(an->rtyp));
7466            if (an->Next() != NULL)
7467            {
7468              res->next = (leftv)omAllocBin(sleftv_bin);
7469              failed=iiExprArith1(res->next,an->next,op);
7470            }
7471            // everything ok, clean up and return
7472            an->CleanUp();
7473            omFreeBin((ADDRESS)an, sleftv_bin);
7474            a->CleanUp();
7475            return failed;
7476          }
7477        }
7478        i++;
7479      }
7480      an->CleanUp();
7481      omFreeBin((ADDRESS)an, sleftv_bin);
7482    }
7483    // error handling
7484    if (!errorreported)
7485    {
7486      if ((at==0) && (a->Fullname()!=sNoName))
7487      {
7488        Werror("`%s` is not defined",a->Fullname());
7489      }
7490      else
7491      {
7492        i=ti;
7493        const char *s = iiTwoOps(op);
7494        Werror("%s(`%s`) failed"
7495                ,s,Tok2Cmdname(at));
7496        if ((!call_failed) && BVERBOSE(V_SHOW_USE))
7497        {
7498          while (dArith1[i].cmd==op)
7499          {
7500            if ((dArith1[i].res!=0)
7501            && (dArith1[i].p!=jjWRONG))
7502              Werror("expected %s(`%s`)"
7503                ,s,Tok2Cmdname(dArith1[i].arg));
7504            i++;
7505          }
7506        }
7507      }
7508    }
7509    res->rtyp = UNKNOWN;
7510  }
7511  a->CleanUp();
7512  return TRUE;
7513}
7514
7515/*=================== operations with 3 args. ============================*/
7516/* must be ordered: first operations for chars (infix ops),
7517 * then alphabetically */
7518
7519BOOLEAN iiExprArith3(leftv res, int op, leftv a, leftv b, leftv c)
7520{
7521  memset(res,0,sizeof(sleftv));
7522  BOOLEAN call_failed=FALSE;
7523
7524  if (!errorreported)
7525  {
7526#ifdef SIQ
7527    if (siq>0)
7528    {
7529      //Print("siq:%d\n",siq);
7530      command d=(command)omAlloc0Bin(sip_command_bin);
7531      memcpy(&d->arg1,a,sizeof(sleftv));
7532      //a->Init();
7533      memcpy(&d->arg2,b,sizeof(sleftv));
7534      //b->Init();
7535      memcpy(&d->arg3,c,sizeof(sleftv));
7536      //c->Init();
7537      d->op=op;
7538      d->argc=3;
7539      res->data=(char *)d;
7540      res->rtyp=COMMAND;
7541      return FALSE;
7542    }
7543#endif
7544    int at=a->Typ();
7545    if (at>MAX_TOK)
7546    {
7547      blackbox *bb=getBlackboxStuff(at);
7548      if (bb!=NULL) return bb->blackbox_Op3(op,res,a,b,c);
7549      else          return TRUE;
7550    }
7551    int bt=b->Typ();
7552    int ct=c->Typ();
7553
7554    iiOp=op;
7555    int i=0;
7556    while ((dArith3[i].cmd!=op)&&(dArith3[i].cmd!=0)) i++;
7557    while (dArith3[i].cmd==op)
7558    {
7559      if ((at==dArith3[i].arg1)
7560      && (bt==dArith3[i].arg2)
7561      && (ct==dArith3[i].arg3))
7562      {
7563        res->rtyp=dArith3[i].res;
7564        if (currRing!=NULL)
7565        {
7566          #ifdef HAVE_PLURAL
7567          if (rIsPluralRing(currRing))
7568          {
7569            if ((dArith3[i].valid_for &PLURAL_MASK)==0 /*NO_PLURAL*/)
7570            {
7571              WerrorS(ii_not_for_plural);
7572              break;
7573            }
7574            else if ((dArith3[i].valid_for &PLURAL_MASK)==2 /*, COMM_PLURAL */)
7575            {
7576              Warn("assume commutative subalgebra for cmd `%s`",Tok2Cmdname(i));
7577            }
7578            /* else, ALLOW_PLURAL */
7579          }
7580          #endif
7581          #ifdef HAVE_RINGS
7582          if (rField_is_Ring(currRing))
7583          {
7584            if ((dArith3[i].valid_for & RING_MASK)==0 /*NO_RING*/)
7585            {
7586              WerrorS(ii_not_for_ring);
7587              break;
7588            }
7589            /* else ALLOW_RING */
7590          }
7591          #endif
7592        }
7593        if (TEST_V_ALLWARN)
7594          Print("call %s(%s,%s,%s)\n",
7595            Tok2Cmdname(iiOp),Tok2Cmdname(at),Tok2Cmdname(bt),Tok2Cmdname(ct));
7596        if ((call_failed=dArith3[i].p(res,a,b,c)))
7597        {
7598          break;// leave loop, goto error handling
7599        }
7600        a->CleanUp();
7601        b->CleanUp();
7602        c->CleanUp();
7603        return FALSE;
7604      }
7605      i++;
7606    }
7607    // implicite type conversion ----------------------------------------------
7608    if (dArith3[i].cmd!=op)
7609    {
7610      int ai,bi,ci;
7611      leftv an = (leftv)omAlloc0Bin(sleftv_bin);
7612      leftv bn = (leftv)omAlloc0Bin(sleftv_bin);
7613      leftv cn = (leftv)omAlloc0Bin(sleftv_bin);
7614      BOOLEAN failed=FALSE;
7615      i=0;
7616      while ((dArith3[i].cmd!=op)&&(dArith3[i].cmd!=0)) i++;
7617      while (dArith3[i].cmd==op)
7618      {
7619        if ((ai=iiTestConvert(at,dArith3[i].arg1))!=0)
7620        {
7621          if ((bi=iiTestConvert(bt,dArith3[i].arg2))!=0)
7622          {
7623            if ((ci=iiTestConvert(ct,dArith3[i].arg3))!=0)
7624            {
7625              res->rtyp=dArith3[i].res;
7626              #ifdef HAVE_PLURAL
7627              if ((currRing!=NULL)
7628              && (rIsPluralRing(currRing)))
7629              {
7630                if ((dArith3[i].valid_for &PLURAL_MASK)==0 /*NO_PLURAL*/)
7631                {
7632                   WerrorS(ii_not_for_plural);
7633                   break;
7634                 }
7635                 else if ((dArith3[i].valid_for &PLURAL_MASK)==2 /*, COMM_PLURAL */)
7636                 {
7637                   Warn("assume commutative subalgebra for cmd `%s`",Tok2Cmdname(i));
7638                 }
7639                 /* else, ALLOW_PLURAL */
7640              }
7641              #endif
7642              if (TEST_V_ALLWARN)
7643                Print("call %s(%s,%s,%s)\n",
7644                  Tok2Cmdname(iiOp),Tok2Cmdname(an->rtyp),
7645                  Tok2Cmdname(bn->rtyp),Tok2Cmdname(cn->rtyp));
7646              failed= ((iiConvert(at,dArith3[i].arg1,ai,a,an))
7647                || (iiConvert(bt,dArith3[i].arg2,bi,b,bn))
7648                || (iiConvert(ct,dArith3[i].arg3,ci,c,cn))
7649                || (call_failed=dArith3[i].p(res,an,bn,cn)));
7650              // everything done, clean up temp. variables
7651              if (failed)
7652              {
7653                // leave loop, goto error handling
7654                break;
7655              }
7656              else
7657              {
7658                // everything ok, clean up and return
7659                an->CleanUp();
7660                bn->CleanUp();
7661                cn->CleanUp();
7662                omFreeBin((ADDRESS)an, sleftv_bin);
7663                omFreeBin((ADDRESS)bn, sleftv_bin);
7664                omFreeBin((ADDRESS)cn, sleftv_bin);
7665                a->CleanUp();
7666                b->CleanUp();
7667                c->CleanUp();
7668        //Print("op: %d,result typ:%d\n",op,res->rtyp);
7669                return FALSE;
7670              }
7671            }
7672          }
7673        }
7674        i++;
7675      }
7676      an->CleanUp();
7677      bn->CleanUp();
7678      cn->CleanUp();
7679      omFreeBin((ADDRESS)an, sleftv_bin);
7680      omFreeBin((ADDRESS)bn, sleftv_bin);
7681      omFreeBin((ADDRESS)cn, sleftv_bin);
7682    }
7683    // error handling ---------------------------------------------------
7684    if (!errorreported)
7685    {
7686      const char *s=NULL;
7687      if ((at==0) && (a->Fullname()!=sNoName))
7688      {
7689        s=a->Fullname();
7690      }
7691      else if ((bt==0) && (b->Fullname()!=sNoName))
7692      {
7693        s=b->Fullname();
7694      }
7695      else if ((ct==0) && (c->Fullname()!=sNoName))
7696      {
7697        s=c->Fullname();
7698      }
7699      if (s!=NULL)
7700        Werror("`%s` is not defined",s);
7701      else
7702      {
7703        i=0;
7704        while ((dArith3[i].cmd!=op)&&(dArith3[i].cmd!=0)) i++;
7705        const char *s = iiTwoOps(op);
7706        Werror("%s(`%s`,`%s`,`%s`) failed"
7707                ,s,Tok2Cmdname(at),Tok2Cmdname(bt),Tok2Cmdname(ct));
7708        if ((!call_failed) && BVERBOSE(V_SHOW_USE))
7709        {
7710          while (dArith3[i].cmd==op)
7711          {
7712            if(((at==dArith3[i].arg1)
7713            ||(bt==dArith3[i].arg2)
7714            ||(ct==dArith3[i].arg3))
7715            && (dArith3[i].res!=0))
7716            {
7717              Werror("expected %s(`%s`,`%s`,`%s`)"
7718                  ,s,Tok2Cmdname(dArith3[i].arg1)
7719                  ,Tok2Cmdname(dArith3[i].arg2)
7720                  ,Tok2Cmdname(dArith3[i].arg3));
7721            }
7722            i++;
7723          }
7724        }
7725      }
7726    }
7727    res->rtyp = UNKNOWN;
7728  }
7729  a->CleanUp();
7730  b->CleanUp();
7731  c->CleanUp();
7732        //Print("op: %d,result typ:%d\n",op,res->rtyp);
7733  return TRUE;
7734}
7735/*==================== operations with many arg. ===============================*/
7736/* must be ordered: first operations for chars (infix ops),
7737 * then alphabetically */
7738
7739BOOLEAN jjANY2LIST(leftv res, leftv v, int cnt)
7740{
7741  // cnt = 0: all
7742  // cnt = 1: only first one
7743  leftv next;
7744  BOOLEAN failed = TRUE;
7745  if(v==NULL) return failed;
7746  res->rtyp = LIST_CMD;
7747  if(cnt) v->next = NULL;
7748  next = v->next;             // saving next-pointer
7749  failed = jjLIST_PL(res, v);
7750  v->next = next;             // writeback next-pointer
7751  return failed;
7752}
7753
7754BOOLEAN iiExprArithM(leftv res, leftv a, int op)
7755{
7756  memset(res,0,sizeof(sleftv));
7757
7758  if (!errorreported)
7759  {
7760#ifdef SIQ
7761    if (siq>0)
7762    {
7763      //Print("siq:%d\n",siq);
7764      command d=(command)omAlloc0Bin(sip_command_bin);
7765      d->op=op;
7766      res->data=(char *)d;
7767      if (a!=NULL)
7768      {
7769        d->argc=a->listLength();
7770        // else : d->argc=0;
7771        memcpy(&d->arg1,a,sizeof(sleftv));
7772        switch(d->argc)
7773        {
7774          case 3:
7775            memcpy(&d->arg3,a->next->next,sizeof(sleftv));
7776            a->next->next->Init();
7777            /* no break */
7778          case 2:
7779            memcpy(&d->arg2,a->next,sizeof(sleftv));
7780            a->next->Init();
7781            a->next->next=d->arg2.next;
7782            d->arg2.next=NULL;
7783            /* no break */
7784          case 1:
7785            a->Init();
7786            a->next=d->arg1.next;
7787            d->arg1.next=NULL;
7788        }
7789        if (d->argc>3) a->next=NULL;
7790        a->name=NULL;
7791        a->rtyp=0;
7792        a->data=NULL;
7793        a->e=NULL;
7794        a->attribute=NULL;
7795        a->CleanUp();
7796      }
7797      res->rtyp=COMMAND;
7798      return FALSE;
7799    }
7800#endif
7801    if ((a!=NULL) && (a->Typ()>MAX_TOK))
7802    {
7803      blackbox *bb=getBlackboxStuff(a->Typ());
7804      if (bb!=NULL) return bb->blackbox_OpM(op,res,a);
7805      else          return TRUE;
7806    }
7807    BOOLEAN failed=FALSE;
7808    int args=0;
7809    if (a!=NULL) args=a->listLength();
7810
7811    iiOp=op;
7812    int i=0;
7813    while ((dArithM[i].cmd!=op)&&(dArithM[i].cmd!=0)) i++;
7814    while (dArithM[i].cmd==op)
7815    {
7816      if ((args==dArithM[i].number_of_args)
7817      || (dArithM[i].number_of_args==-1)
7818      || ((dArithM[i].number_of_args==-2)&&(args>0)))
7819      {
7820        res->rtyp=dArithM[i].res;
7821        if (currRing!=NULL)
7822        {
7823          #ifdef HAVE_PLURAL
7824          if (rIsPluralRing(currRing))
7825          {
7826            if ((dArithM[i].valid_for &PLURAL_MASK)==0 /*NO_PLURAL*/)
7827            {
7828              WerrorS(ii_not_for_plural);
7829              break;
7830            }
7831            else if ((dArithM[i].valid_for &PLURAL_MASK)==2 /*, COMM_PLURAL */)
7832            {
7833              Warn("assume commutative subalgebra for cmd `%s`",Tok2Cmdname(i));
7834            }
7835            /* else ALLOW_PLURAL */
7836          }
7837          #endif
7838          #ifdef HAVE_RINGS
7839          if (rField_is_Ring(currRing))
7840          {
7841            if ((dArithM[i].valid_for & RING_MASK)==0 /*NO_RING*/)
7842            {
7843              WerrorS(ii_not_for_ring);
7844              break;
7845            }
7846            /* else ALLOW_RING */
7847          }
7848          #endif
7849        }
7850        if (TEST_V_ALLWARN)
7851          Print("call %s(... (%d args))\n", Tok2Cmdname(iiOp),args);
7852        if (dArithM[i].p(res,a))
7853        {
7854          break;// leave loop, goto error handling
7855        }
7856        if (a!=NULL) a->CleanUp();
7857        //Print("op: %d,result typ:%d\n",op,res->rtyp);
7858        return failed;
7859      }
7860      i++;
7861    }
7862    // error handling
7863    if (!errorreported)
7864    {
7865      if ((args>0) && (a->rtyp==0) && (a->Name()!=sNoName))
7866      {
7867        Werror("`%s` is not defined",a->Fullname());
7868      }
7869      else
7870      {
7871        const char *s = iiTwoOps(op);
7872        Werror("%s(...) failed",s);
7873      }
7874    }
7875    res->rtyp = UNKNOWN;
7876  }
7877  if (a!=NULL) a->CleanUp();
7878        //Print("op: %d,result typ:%d\n",op,res->rtyp);
7879  return TRUE;
7880}
7881
7882/*=================== general utilities ============================*/
7883int IsCmd(const char *n, int & tok)
7884{
7885  int i;
7886  int an=1;
7887  int en=sArithBase.nLastIdentifier;
7888
7889  loop
7890  //for(an=0; an<sArithBase.nCmdUsed; )
7891  {
7892    if(an>=en-1)
7893    {
7894      if (strcmp(n, sArithBase.sCmds[an].name) == 0)
7895      {
7896        i=an;
7897        break;
7898      }
7899      else if ((an!=en) && (strcmp(n, sArithBase.sCmds[en].name) == 0))
7900      {
7901        i=en;
7902        break;
7903      }
7904      else
7905      {
7906        // -- blackbox extensions:
7907        // return 0;
7908        return blackboxIsCmd(n,tok);
7909      }
7910    }
7911    i=(an+en)/2;
7912    if (*n < *(sArithBase.sCmds[i].name))
7913    {
7914      en=i-1;
7915    }
7916    else if (*n > *(sArithBase.sCmds[i].name))
7917    {
7918      an=i+1;
7919    }
7920    else
7921    {
7922      int v=strcmp(n,sArithBase.sCmds[i].name);
7923      if(v<0)
7924      {
7925        en=i-1;
7926      }
7927      else if(v>0)
7928      {
7929        an=i+1;
7930      }
7931      else /*v==0*/
7932      {
7933        break;
7934      }
7935    }
7936  }
7937  lastreserved=sArithBase.sCmds[i].name;
7938  tok=sArithBase.sCmds[i].tokval;
7939  if(sArithBase.sCmds[i].alias==2)
7940  {
7941    Warn("outdated identifier `%s` used - please change your code",
7942    sArithBase.sCmds[i].name);
7943    sArithBase.sCmds[i].alias=1;
7944  }
7945  if (currRingHdl==NULL)
7946  {
7947    #ifdef SIQ
7948    if (siq<=0)
7949    {
7950    #endif
7951      if ((tok>=BEGIN_RING) && (tok<=END_RING))
7952      {
7953        WerrorS("no ring active");
7954        return 0;
7955      }
7956    #ifdef SIQ
7957    }
7958    #endif
7959  }
7960  if (!expected_parms)
7961  {
7962    switch (tok)
7963    {
7964      case IDEAL_CMD:
7965      case INT_CMD:
7966      case INTVEC_CMD:
7967      case MAP_CMD:
7968      case MATRIX_CMD:
7969      case MODUL_CMD:
7970      case POLY_CMD:
7971      case PROC_CMD:
7972      case RING_CMD:
7973      case STRING_CMD:
7974        cmdtok = tok;
7975        break;
7976    }
7977  }
7978  return sArithBase.sCmds[i].toktype;
7979}
7980static int iiTabIndex(const jjValCmdTab dArithTab, const int len, const int op)
7981{
7982  int a=0;
7983  int e=len;
7984  int p=len/2;
7985  do
7986  {
7987     if (op==dArithTab[p].cmd) return dArithTab[p].start;
7988     if (op<dArithTab[p].cmd) e=p-1;
7989     else   a = p+1;
7990     p=a+(e-a)/2;
7991  }
7992  while ( a <= e);
7993
7994  assume(0);
7995  return 0;
7996}
7997
7998const char * Tok2Cmdname(int tok)
7999{
8000  int i = 0;
8001  if (tok <= 0)
8002  {
8003    return sArithBase.sCmds[0].name;
8004  }
8005  if (tok==ANY_TYPE) return "any_type";
8006  if (tok==COMMAND) return "command";
8007  if (tok==NONE) return "nothing";
8008  //if (tok==IFBREAK) return "if_break";
8009  //if (tok==VECTOR_FROM_POLYS) return "vector_from_polys";
8010  //if (tok==ORDER_VECTOR) return "ordering";
8011  //if (tok==REF_VAR) return "ref";
8012  //if (tok==OBJECT) return "object";
8013  //if (tok==PRINT_EXPR) return "print_expr";
8014  if (tok==IDHDL) return "identifier";
8015  if (tok>MAX_TOK) return getBlackboxName(tok);
8016  for(i=0; i<sArithBase.nCmdUsed; i++)
8017    //while (sArithBase.sCmds[i].tokval!=0)
8018  {
8019    if ((sArithBase.sCmds[i].tokval == tok)&&
8020        (sArithBase.sCmds[i].alias==0))
8021    {
8022      return sArithBase.sCmds[i].name;
8023    }
8024  }
8025  return sArithBase.sCmds[0].name;
8026}
8027
8028
8029/*---------------------------------------------------------------------*/
8030/**
8031 * @brief compares to entry of cmdsname-list
8032
8033 @param[in] a
8034 @param[in] b
8035
8036 @return <ReturnValue>
8037**/
8038/*---------------------------------------------------------------------*/
8039static int _gentable_sort_cmds( const void *a, const void *b )
8040{
8041  cmdnames *pCmdL = (cmdnames*)a;
8042  cmdnames *pCmdR = (cmdnames*)b;
8043
8044  if(a==NULL || b==NULL)             return 0;
8045
8046  /* empty entries goes to the end of the list for later reuse */
8047  if(pCmdL->name==NULL) return 1;
8048  if(pCmdR->name==NULL) return -1;
8049
8050  /* $INVALID$ must come first */
8051  if(strcmp(pCmdL->name, "$INVALID$")==0) return -1;
8052  if(strcmp(pCmdR->name, "$INVALID$")==0) return  1;
8053
8054  /* tokval=-1 are reserved names at the end */
8055  if (pCmdL->tokval==-1)
8056  {
8057    if (pCmdR->tokval==-1)
8058       return strcmp(pCmdL->name, pCmdR->name);
8059    /* pCmdL->tokval==-1, pCmdL goes at the end */
8060    return 1;
8061  }
8062  /* pCmdR->tokval==-1, pCmdR goes at the end */
8063  if(pCmdR->tokval==-1) return -1;
8064
8065  return strcmp(pCmdL->name, pCmdR->name);
8066}
8067
8068/*---------------------------------------------------------------------*/
8069/**
8070 * @brief initialisation of arithmetic structured data
8071
8072 @retval 0 on success
8073
8074**/
8075/*---------------------------------------------------------------------*/
8076int iiInitArithmetic()
8077{
8078  int i;
8079  //printf("iiInitArithmetic()\n");
8080  memset(&sArithBase, 0, sizeof(sArithBase));
8081  iiInitCmdName();
8082  /* fix last-identifier */
8083#if 0
8084  /* we expect that gentable allready did every thing */
8085  for(sArithBase.nLastIdentifier=sArithBase.nCmdUsed-1;
8086      sArithBase.nLastIdentifier>0; sArithBase.nLastIdentifier--) {
8087    if(sArithBase.sCmds[sArithBase.nLastIdentifier].tokval>=0) break;
8088  }
8089#endif
8090  //Print("L=%d\n", sArithBase.nLastIdentifier);
8091
8092  //iiArithAddCmd(szName, nAlias, nTokval, nToktype);
8093  //iiArithAddCmd("mygcd", 1, GCD_CMD, CMD_2);
8094
8095  //iiArithAddCmd("Top", 0,-1,0);
8096
8097
8098  //for(i=0; i<sArithBase.nCmdUsed; i++) {
8099  //  printf("CMD[%03d] %s, %d, %d, %d\n", i,
8100  //         sArithBase.sCmds[i].name,
8101  //         sArithBase.sCmds[i].alias,
8102  //         sArithBase.sCmds[i].tokval,
8103  //         sArithBase.sCmds[i].toktype);
8104  //}
8105  //iiArithRemoveCmd("Top");
8106  //iiArithAddCmd("mygcd", 2, GCD_CMD, CMD_2);
8107  //iiArithRemoveCmd("mygcd");
8108  //iiArithAddCmd("kkk", 1, 1234, CMD_1);
8109  return 0;
8110}
8111
8112/*---------------------------------------------------------------------*/
8113/**
8114 * @brief append newitem of size sizeofitem to the list named list.
8115
8116 @param[in,out] list
8117 @param[in,out] item_count
8118 @param[in] sizeofitem
8119 @param[in] newitem
8120
8121 @retval  0 success
8122 @retval -1 failure
8123**/
8124/*---------------------------------------------------------------------*/
8125int iiArithAddItem2list(
8126  void **list,
8127  long  *item_count,
8128  long sizeofitem,
8129  void *newitem
8130  )
8131{
8132  int count = *item_count;
8133
8134  //TRACE(0, "add_item_to_list(%p, %p, %ld, %p)\n", list, item_count,
8135  //       sizeofitem, newitem);
8136
8137  if(count==0)
8138  {
8139    *list = (void *)omAlloc(sizeofitem);
8140  }
8141  else
8142  {
8143    *list = (void *)omRealloc(*list, (count+1) * sizeofitem);
8144  }
8145  if((*list)==NULL) return -1;
8146
8147  //memset((*list)+count*sizeofitem, 0, sizeofitem);
8148  //memcpy((*list)+count*sizeofitem, newitem, sizeofitem);
8149
8150  /* erhoehe counter um 1 */
8151  (count)++;
8152  *item_count = count;
8153  return 0;
8154}
8155
8156int iiArithFindCmd(const char *szName)
8157{
8158  int an=0;
8159  int i = 0,v = 0;
8160  int en=sArithBase.nLastIdentifier;
8161
8162  loop
8163  //for(an=0; an<sArithBase.nCmdUsed; )
8164  {
8165    if(an>=en-1)
8166    {
8167      if (strcmp(szName, sArithBase.sCmds[an].name) == 0)
8168      {
8169        //Print("RET-an=%d %s\n", an, sArithBase.sCmds[an].name);
8170        return an;
8171      }
8172      else if (strcmp(szName, sArithBase.sCmds[en].name) == 0)
8173      {
8174        //Print("RET-en=%d %s\n", en, sArithBase.sCmds[en].name);
8175        return en;
8176      }
8177      else
8178      {
8179        //Print("RET- 1\n");
8180        return -1;
8181      }
8182    }
8183    i=(an+en)/2;
8184    if (*szName < *(sArithBase.sCmds[i].name))
8185    {
8186      en=i-1;
8187    }
8188    else if (*szName > *(sArithBase.sCmds[i].name))
8189    {
8190      an=i+1;
8191    }
8192    else
8193    {
8194      v=strcmp(szName,sArithBase.sCmds[i].name);
8195      if(v<0)
8196      {
8197        en=i-1;
8198      }
8199      else if(v>0)
8200      {
8201        an=i+1;
8202      }
8203      else /*v==0*/
8204      {
8205        //Print("RET-i=%d %s\n", i, sArithBase.sCmds[i].name);
8206        return i;
8207      }
8208    }
8209  }
8210  //if(i>=0 && i<sArithBase.nCmdUsed)
8211  //  return i;
8212  //Print("RET-2\n");
8213  return -2;
8214}
8215
8216char *iiArithGetCmd( int nPos )
8217{
8218  if(nPos<0) return NULL;
8219  if(nPos<sArithBase.nCmdUsed)
8220    return sArithBase.sCmds[nPos].name;
8221  return NULL;
8222}
8223
8224int iiArithRemoveCmd(const char *szName)
8225{
8226  int nIndex;
8227  if(szName==NULL) return -1;
8228
8229  nIndex = iiArithFindCmd(szName);
8230  if(nIndex<0 || nIndex>=sArithBase.nCmdUsed)
8231  {
8232    Print("'%s' not found (%d)\n", szName, nIndex);
8233    return -1;
8234  }
8235  omFree(sArithBase.sCmds[nIndex].name);
8236  sArithBase.sCmds[nIndex].name=NULL;
8237  qsort(sArithBase.sCmds, sArithBase.nCmdUsed, sizeof(cmdnames),
8238        (&_gentable_sort_cmds));
8239  sArithBase.nCmdUsed--;
8240
8241  /* fix last-identifier */
8242  for(sArithBase.nLastIdentifier=sArithBase.nCmdUsed-1;
8243      sArithBase.nLastIdentifier>0; sArithBase.nLastIdentifier--)
8244  {
8245    if(sArithBase.sCmds[sArithBase.nLastIdentifier].tokval>=0) break;
8246  }
8247  //Print("L=%d\n", sArithBase.nLastIdentifier);
8248  return 0;
8249}
8250
8251int iiArithAddCmd(
8252  const char *szName,
8253  short nAlias,
8254  short nTokval,
8255  short nToktype,
8256  short nPos
8257  )
8258{
8259  //printf("AddCmd(%s, %d, %d, %d, %d)\n", szName, nAlias,
8260  //       nTokval, nToktype, nPos);
8261  if(nPos>=0)
8262  {
8263    // no checks: we rely on a correct generated code in iparith.inc
8264    assume(nPos < sArithBase.nCmdAllocated);
8265    assume(szName!=NULL);
8266    sArithBase.sCmds[nPos].name    = omStrDup(szName);
8267    sArithBase.sCmds[nPos].alias   = nAlias;
8268    sArithBase.sCmds[nPos].tokval  = nTokval;
8269    sArithBase.sCmds[nPos].toktype = nToktype;
8270    sArithBase.nCmdUsed++;
8271    //if(nTokval>0) sArithBase.nLastIdentifier++;
8272  }
8273  else
8274  {
8275    if(szName==NULL) return -1;
8276    int nIndex = iiArithFindCmd(szName);
8277    if(nIndex>=0)
8278    {
8279      Print("'%s' already exists at %d\n", szName, nIndex);
8280      return -1;
8281    }
8282
8283    if(sArithBase.nCmdUsed>=sArithBase.nCmdAllocated)
8284    {
8285      /* needs to create new slots */
8286      unsigned long nSize = (sArithBase.nCmdAllocated+1)*sizeof(cmdnames);
8287      sArithBase.sCmds = (cmdnames *)omRealloc(sArithBase.sCmds, nSize);
8288      if(sArithBase.sCmds==NULL) return -1;
8289      sArithBase.nCmdAllocated++;
8290    }
8291    /* still free slots available */
8292    sArithBase.sCmds[sArithBase.nCmdUsed].name    = omStrDup(szName);
8293    sArithBase.sCmds[sArithBase.nCmdUsed].alias   = nAlias;
8294    sArithBase.sCmds[sArithBase.nCmdUsed].tokval  = nTokval;
8295    sArithBase.sCmds[sArithBase.nCmdUsed].toktype = nToktype;
8296    sArithBase.nCmdUsed++;
8297
8298    qsort(sArithBase.sCmds, sArithBase.nCmdUsed, sizeof(cmdnames),
8299          (&_gentable_sort_cmds));
8300    for(sArithBase.nLastIdentifier=sArithBase.nCmdUsed-1;
8301        sArithBase.nLastIdentifier>0; sArithBase.nLastIdentifier--)
8302    {
8303      if(sArithBase.sCmds[sArithBase.nLastIdentifier].tokval>=0) break;
8304    }
8305    //Print("L=%d\n", sArithBase.nLastIdentifier);
8306  }
8307  return 0;
8308}
Note: See TracBrowser for help on using the repository browser.