source: git/Singular/mpsr_GetPoly.cc @ 97454d

spielwiese
Last change on this file since 97454d was 97454d, checked in by Olaf Bachmann <obachman@…>, 26 years ago
1998-04-07 Olaf Bachmann <obachman@mathematik.uni-kl.de> * mpsr_Put.cc (mpsr_PutDump): dump does not dump LIB string any more * extra.cc (jjSYSTEM): added System("whoami") to return full executable pathname of running Singular git-svn-id: file:///usr/local/Singular/svn/trunk@1355 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 25.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/* $Id: mpsr_GetPoly.cc,v 1.15 1998-04-07 18:35:26 obachman Exp $ */
6
7/***************************************************************
8 *
9 * File:       mpsr_GetPoly.cc
10 * Purpose:    rotines which get polys and polynomails (i.e. ring) annotations
11 * Author:     Olaf Bachmann (2/97)
12 *
13 *
14 ***************************************************************/
15#include "mod2.h"
16
17#ifdef HAVE_MPSR
18#include "limits.h"
19
20#include "mpsr_Get.h"
21
22#include "gmp.h"
23#include "mmemory.h"
24#include "tok.h"
25#include "ring.h"
26#include "ipid.h"
27#include "longalg.h"
28#include "maps.h"
29#include "ideals.h"
30#include "grammar.h"
31#include "febase.h"
32#include "modulop.h"
33
34#include "mpsr_Tok.h"
35
36#ifdef PARI_BIGINT_TEST
37#include "MP_PariBigInt.h"
38
39MP_Status_t IMP_MyGetApInt(MP_Link_pt link, MP_ApInt_t *apint)
40{
41  GEN pnum;
42  mp_failr(IMP_GetApInt(link, (MP_ApInt_t *) &pnum));
43  _pari_to_gmp(pnum, (mpz_ptr *) apint);
44
45  return MP_Success;
46}
47
48#else
49
50#define IMP_MyGetApInt IMP_GetApInt
51
52#endif
53
54
55/***************************************************************
56 *
57 * global variable definitions
58 *
59 ***************************************************************/
60
61static mpsr_Status_t (*GetCoeff)(MP_Link_pt link, number *x);
62static mpsr_Status_t (*GetAlgNumberNumber)(MP_Link_pt link, number *x);
63static MP_Sint32_t gNalgvars = 0;
64static MP_Sint32_t gNvars = 0;
65static MP_Sint32_t *gTa = NULL;
66static ring        currGetRing = NULL;
67
68
69/***************************************************************
70 *
71 * prototype declarations
72 *
73 ***************************************************************/
74static void        SetGetFuncs(ring r);
75static mpsr_Status_t GetModuloNumber(MP_Link_pt link, number *a);
76static mpsr_Status_t GetGaloisNumber(MP_Link_pt link, number *a);
77static mpsr_Status_t GetFloatNumber(MP_Link_pt link, number *a);
78static mpsr_Status_t GetApInt(MP_Link_pt link, mpz_ptr ap);
79static mpsr_Status_t GetRationalNumber(MP_Link_pt link, number *a);
80static mpsr_Status_t GetAlgNumber(MP_Link_pt link, number *a);
81static mpsr_Status_t GetVarNumberAnnot(MPT_Node_pt node, ring r, BOOLEAN mv);
82static mpsr_Status_t GetProtoTypeAnnot(MPT_Node_pt node, ring r, BOOLEAN mv,
83                                     ring &subring);
84static mpsr_Status_t GetOrderingAnnot(MPT_Node_pt node, ring r, BOOLEAN mv);
85static mpsr_Status_t GetSimpleOrdering(MPT_Node_pt node, ring r, short i);
86static mpsr_Status_t GetVarNamesAnnot(MPT_Node_pt node, ring r);
87static mpsr_Status_t GetDefRelsAnnot(MPT_Node_pt node, ring r);
88
89/***************************************************************
90 *
91 * Setting the global Put Functions
92 *
93 ***************************************************************/
94
95static inline BOOLEAN IsCurrGetRing(ring r)
96{
97  if (r == currGetRing && r == currRing) return 1;
98  else return 0;
99}
100
101static void SetGetFuncs(ring r)
102{
103  currGetRing = r;
104  // first, we set the PutNumber function
105  if (r->N != gNvars)
106  {
107    if (gTa != NULL)
108      Free(gTa, (gNvars+1)*sizeof(MP_Sint32_t));
109
110    gNvars = r->N;
111    if (gNvars > 1)
112      gTa = (MP_Sint32_t *) Alloc((gNvars+1)*sizeof(MP_Sint32_t));
113    else
114      gTa = NULL;
115  }
116
117  if ((r->ch) == 0)
118    // rational numbers
119    GetCoeff = GetRationalNumber;
120  else if ((r->ch) > 1)
121  {
122    if (r->parameter == NULL)
123      GetCoeff = GetModuloNumber;
124    else
125      GetCoeff = GetGaloisNumber;
126  }
127  else if ((r->ch) == -1)
128    GetCoeff = GetFloatNumber;
129  else
130  {
131    // now we come to algebraic numbers
132    gNalgvars = rPar(r);
133    GetCoeff = GetAlgNumber;
134    if ((r->ch) < 0)
135      // first, Z/p(a)
136      GetAlgNumberNumber = GetModuloNumber;
137    else
138      GetAlgNumberNumber = GetRationalNumber;
139  }
140 
141  // still need to set the global ring
142  mpsr_SetCurrRing(r, TRUE);
143}
144
145
146
147/***************************************************************
148 *
149 * Routines for Getting coeffs
150 *
151 ***************************************************************/
152// we always Get modulo numbers without a node, since
153// we have type-spec this before
154static mpsr_Status_t GetModuloNumber(MP_Link_pt link, number *a)
155{
156  MP_Uint32_t x;
157  mp_failr(IMP_GetUint32(link, &x));
158  *a=npInit((int)x);
159  return mpsr_Success;
160}
161
162static mpsr_Status_t GetGaloisNumber(MP_Link_pt link, number *a)
163{
164  mp_return(IMP_GetUint32(link, (MP_Uint32_t *) a));
165}
166
167static mpsr_Status_t GetFloatNumber(MP_Link_pt link, number *a)
168{
169   mp_return( IMP_GetReal32(link , (MP_Real32_t *) a));
170}
171
172static mpsr_Status_t GetApInt(MP_Link_pt link, mpz_ptr ap)
173{
174  MP_NodeType_t     node;
175  MP_DictTag_t      dict;
176  MP_NumChild_t     num_child;
177  MP_NumAnnot_t     num_annots;
178  MP_Common_t       cvalue;
179  MP_Boolean_t      req = 0;
180 
181  mp_failr(IMP_GetNodeHeader(link,&node,&dict, &cvalue, &num_annots,
182                             &num_child));
183
184  if (node == MP_ApIntType)
185  {
186    mpz_init(ap);
187    mp_failr(IMP_MyGetApInt(link, (MP_ApInt_t *) &ap));
188  }
189  else if (node == MP_Sint32Type || node == MP_Sint8Type)
190  {
191    MP_Sint32_t i;
192    if (node == MP_Sint8Type)
193      i = (int) ((signed char) cvalue);
194    else
195      mp_failr(IMP_GetSint32(link, &i));
196    mpz_init_set_si((mpz_ptr) ap, i);
197  }
198  else if (node == MP_Uint32Type || node == MP_Uint8Type)
199  {
200    MP_Uint32_t i;
201    if (node == MP_Uint8Type)
202      i = cvalue;
203    else
204      mp_failr(IMP_GetUint32(link, &i));
205    mpz_init_set_ui((mpz_ptr) ap, i);
206  }
207  else
208    return mpsr_SetError(mpsr_WrongNodeType);
209 
210  if (num_annots > 0)
211  {
212    mpt_failr(MPT_SkipAnnots(link, num_annots, &req));
213    if (req) return mpsr_SetError(mpsr_ReqAnnotSkip);
214  }
215 
216  return mpsr_Success;
217}
218   
219// This supposes that number is of char 0, i.e. a rational number
220static mpsr_Status_t GetRationalNumber(MP_Link_pt link, number *x)
221{
222  MP_NodeType_t     node;
223  MP_DictTag_t      dict;
224  MP_NumChild_t     num_child;
225  MP_NumAnnot_t     num_annots;
226  MP_Sint32_t       i;
227  MP_Common_t       cvalue;
228  number            y;
229  MP_Boolean_t      req;
230
231  mp_failr(IMP_GetNodeHeader(link,&node,&dict, &cvalue, &num_annots,
232                             &num_child));
233
234  // start with the most frequent cases
235  if (node == MP_Sint32Type) 
236  {
237    mp_failr(IMP_GetSint32(link, &i));
238    *x = nlInit(i);
239  }
240  else if (node == MP_ApIntType)
241  {
242    mpz_ptr gnum;
243    y =  (number) Alloc0(sizeof(rnumber));
244#ifdef LDEBUG
245    y->debug = 123456;
246#endif
247    y->s = 3;
248    gnum = &(y->z);
249    mpz_init(gnum);
250    mp_failr(IMP_MyGetApInt(link, (MP_ApInt_t *) &gnum));
251    *x = nlInit(y);
252  }
253  // fraction of numbers
254  else if (node == MP_CommonOperatorType &&
255           dict== MP_BasicDict &&
256           cvalue == MP_CopBasicDiv)
257  {
258    if (num_annots > 0)
259    {
260      mpt_failr(MPT_SkipAnnots(link, num_annots, &req));
261      if (req) return mpsr_SetError(mpsr_ReqAnnotSkip);
262    }
263    *x =  (number) Alloc0(sizeof(rnumber));
264    y = (number) *x;
265#ifdef LDEBUG
266    y->debug = 123456;
267#endif
268    y->s = 1;
269    failr(GetApInt(link, &(y->z)));
270    return GetApInt(link, &(y->n));
271  }
272  // check for some more esoteric cases
273  else if (node == MP_Uint8Type)
274    *x = nlInit(cvalue);
275  else if (node == MP_Sint8Type)
276    // be careful -- need to handle the value "-2", for example
277    *x = nlInit((int) ((MP_Sint8_t) cvalue));
278  else if (node == MP_Uint32Type)
279  {
280    MP_Uint32_t ui;
281    mp_failr(IMP_GetUint32(link, &ui));
282    // check whether u_int can be casted safely to int
283    if (ui < INT_MAX)
284      *x = nlInit(i);
285    else
286    {
287      // otherwise, make an apint out of it
288      *x =  (number) Alloc0(sizeof(rnumber));
289      y = (number) *x;
290#ifdef LDEBUG
291      y->debug = 123456;
292#endif
293      mpz_init_set_ui(&(y->z), ui);
294      y->s = 3;
295    }
296  }
297  else
298    return mpsr_SetError(mpsr_WrongNodeType);
299 
300  if (num_annots > 0)
301  {
302    mpt_failr(MPT_SkipAnnots(link, num_annots, &req));
303    if (req) return mpsr_SetError(mpsr_ReqAnnotSkip);
304  }
305
306  return mpsr_Success;
307}
308
309/***************************************************************
310 *
311 * Algebraic Numbers (a la Singular)
312 *
313 ***************************************************************/
314static inline mpsr_Status_t GetAlgPoly(MP_Link_pt link, alg *p)
315{
316  MP_Uint32_t j, nm;
317  int *exp;
318  alg a;
319
320  IMP_GetUint32(link, &nm);
321
322  if (nm == 0)
323  {
324    *p = NULL;
325    return mpsr_Success;
326  }
327  a = napNew();
328  *p = a;
329
330  failr(GetAlgNumberNumber(link, &(a->ko)));
331  exp = &(a->e[0]);
332  mp_failr(IMP_GetSint32Vector(link, (MP_Sint32_t **) &exp, naNumbOfPar));
333
334  for (j=1; j<nm; j++)
335  {
336    a->ne = napNew();
337    a = a->ne;
338    failr(GetAlgNumberNumber(link, &(a->ko)));
339    exp = &(a->e[0]);
340    mp_failr(IMP_GetSint32Vector(link, (MP_Sint32_t **) &exp, naNumbOfPar));
341  }
342  a->ne = NULL;
343
344  return mpsr_Success;
345}
346
347static mpsr_Status_t GetAlgNumber(MP_Link_pt link, number *a)
348{
349  lnumber b;
350  MP_Uint32_t ut;
351
352  // Get the union tag
353  mp_failr(IMP_GetUint32(link, &ut));
354  if (ut == 0)
355  {
356    *a = NULL;
357    return mpsr_Success;
358  }
359  else if (ut == 1 || ut == 2)
360  {
361    // single number
362    b = (lnumber) Alloc0(sizeof(rnumber));
363    *a = (number) b;
364    failr(GetAlgPoly(link, &(b->z)));
365    if (ut == 2)
366      return GetAlgPoly(link, &(b->n));
367    else
368      return mpsr_Success;
369  }
370  else
371    return mpsr_SetError(mpsr_WrongUnionDiscriminator);
372}
373
374/***************************************************************
375 *
376 *  Getting polys
377 *
378 ***************************************************************/
379mpsr_Status_t mpsr_GetPoly(MP_Link_pt link, poly &p, MP_Uint32_t nmon,
380                         ring cring)
381{
382  poly pp;
383  MP_Sint32_t i;
384  MP_Uint32_t j;
385
386  if (! IsCurrGetRing(cring))
387    SetGetFuncs(cring);
388 
389  if (nmon == 0)
390  {
391    p = NULL;
392    return mpsr_Success;
393  }
394 
395  pp = pInit();
396  p = pp;
397  failr(GetCoeff(link, &(pp->coef)));
398  if (gNvars > 1)
399  {
400    MP_Sint32_t* Ta = &gTa[1];
401    mp_failr(IMP_GetSint32Vector(link, &Ta, gNvars));
402    for (i=1; i<=gNvars; i++)
403      pSetExp(pp,i , (Exponent_t) gTa[i]);
404    pSetm(pp);
405
406    for (j=1; j<nmon; j++)
407    {
408      pp->next = pInit();
409      pp = pp->next;
410      failr(GetCoeff(link, &(pp->coef)));
411      mp_failr(IMP_GetSint32Vector(link, &Ta, gNvars));
412      for (i=1; i<=gNvars; i++)
413        pSetExp(pp, i, (Exponent_t) gTa[i]);
414      pSetm(pp);
415    }
416  }
417  else
418  {
419    mp_failr(IMP_GetSint32(link, &i));
420    pSetExp(pp,1, (Exponent_t) i);
421    pSetm(pp);
422   
423    for (j=1; j<nmon; j++)
424    {
425      pp->next = pInit();
426      pp = pp->next;
427      failr(GetCoeff(link, &(pp->coef)));
428      mp_failr(IMP_GetSint32(link, &i));
429      pSetExp(pp,1, (Exponent_t) i);
430      pSetm(pp);
431    }
432  }
433
434  pp->next = NULL;
435
436  pTest(p);
437  return mpsr_Success;
438}
439
440mpsr_Status_t mpsr_GetPolyVector(MP_Link_pt link, poly &p, MP_Uint32_t nmon,
441                          ring cring)
442{
443  poly pp;
444  MP_Sint32_t i, n1;
445  MP_Uint32_t j;
446
447  if (!IsCurrGetRing(cring))
448    SetGetFuncs(cring);
449 
450  n1 = gNvars + 1;
451  if (nmon == 0)
452  {
453    p = NULL;
454    return mpsr_Success;
455  }
456 
457  pp = pInit();
458  p = pp;
459  failr(GetCoeff(link, &(pp->coef)));
460  if (gNvars > 1)
461  {
462    mp_failr(IMP_GetSint32Vector(link, &gTa, n1));
463    pGetComp(pp) = gTa[0];
464    for (i=1; i<n1; i++)
465      pSetExp(pp, i, (Exponent_t) gTa[i]);
466    pSetm(pp);
467
468    for (j=1; j<nmon; j++)
469    {
470      pp->next = pInit();
471      pp = pp->next;
472      failr(GetCoeff(link, &(pp->coef)));
473      mp_failr(IMP_GetSint32Vector(link, &gTa, n1));
474      pGetComp(pp) =  gTa[0];
475      for (i=1; i<n1; i++)
476        pSetExp(pp,i, (Exponent_t) gTa[i]);
477      pSetm(pp);
478    }
479  }
480  else
481  {
482    mp_failr(IMP_GetSint32(link, &i));
483    pGetComp(pp) = (Exponent_t) i;
484    mp_failr(IMP_GetSint32(link, &i));
485    pSetExp(pp,1, (Exponent_t) i);
486    pSetm(pp);
487   
488    for (j=1; j<nmon; j++)
489    {
490      pp->next = pInit();
491      pp = pp->next;
492      failr(GetCoeff(link, &(pp->coef)));
493      mp_failr(IMP_GetSint32(link, &i));
494      pGetComp(pp) = (Exponent_t) i;
495      mp_failr(IMP_GetSint32(link, &i));
496      pSetExp(pp,1, (Exponent_t) i);
497      pSetm(pp);
498    }
499  }
500  pp->next = NULL;
501
502  pTest(p);
503  return mpsr_Success;
504}
505
506/***************************************************************
507 *
508 *  The Getting annotation buisness
509 *
510 ***************************************************************/
511#define falser(x)                               \
512do                                              \
513{                                               \
514  if (!(x)) return mpsr_Failure;                   \
515}                                               \
516while (0)
517
518// We assume that the node is that of a DDP: This returns
519// MP_Succcess, if annots of node can be used to construct a
520// Singular ring (in which case r is the respective ring) or,
521// MP_Failure, if not
522mpsr_Status_t mpsr_GetRingAnnots(MPT_Node_pt node, ring &r, BOOLEAN &mv)
523{
524  sip_sring r1, *subring;
525  poly minpoly = NULL;
526
527  memset(&r1, 0, sizeof(sip_sring));
528
529  r = NULL;
530  if (MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyModuleVector) != NULL)
531    mv = 1;
532  else
533    mv = 0;
534
535  // sets r->N
536  if (GetVarNumberAnnot(node, &r1, mv) != mpsr_Success)
537    Warn("GetVarNumberAnnot: using the one found in the prototype");
538
539  // sets r->char and r->minpoly, r->parameter; if necessary
540  failr(GetProtoTypeAnnot(node, &r1, mv, subring));
541
542  // if we are still here, then we are successful in constructing the ring
543  r = (ring) Alloc(sizeof(sip_sring));
544  memcpy(r, &r1, sizeof(sip_sring));
545
546  if (GetVarNamesAnnot(node, r) != mpsr_Success)
547    Warn("GetVarNamesAnnot: using default variable names");
548
549  if (GetOrderingAnnot(node,r, mv) != mpsr_Success)
550    Warn("GetOrderingAnnot: using unspec ordering");
551
552  if (GetDefRelsAnnot(node, r) != mpsr_Success)
553    Warn("GetDefRelsAnnot: using no defining relations");
554
555  // check on whether or not I have to set a minpoly
556  if (subring != NULL)
557  {
558    if ((subring->qideal != NULL) &&
559        ((minpoly = subring->qideal->m[0]) != NULL))
560    {
561      mpsr_SetCurrRing(r, TRUE);
562      minpoly = maIMap(subring, minpoly);
563      r->minpoly = minpoly->coef;
564      pFree1(minpoly);
565    }
566    rKill(subring);
567  }
568
569  // complete ring constructions
570  rComplete(r);
571  return mpsr_Success;
572}
573
574
575static mpsr_Status_t GetVarNumberAnnot(MPT_Node_pt node, ring r, BOOLEAN mv)
576{
577  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyVarNumber);
578
579  if (annot != NULL) 
580  {
581    if (annot->value != NULL && annot->value->node->type == MP_Uint32Type)
582    {
583      // Hm.. should check that r->N is not too big for Singular
584      r->N = (short) MP_UINT32_T(annot->value->node->nvalue);
585      if (mv) (r->N)--;
586      return mpsr_Success;
587    }
588  }
589  return mpsr_Failure;
590}
591
592         
593static mpsr_Status_t GetProtoTypeAnnot(MPT_Node_pt node, ring r, BOOLEAN mv,
594                                     ring &subring)
595{
596  MPT_Annot_pt annot = NULL;
597  MPT_Tree_pt  val;
598  MPT_Tree_pt  *ta;
599
600  subring = NULL;
601 
602  // look for prototype annot
603  if ((val = MPT_GetProtoTypespec(node)) == NULL)
604    return mpsr_Failure;
605
606  // check value of annot
607  node = val->node;
608  if (! (NodeCheck(node, MP_CommonOperatorType, MP_ProtoDict,
609                   MP_CopProtoStruct) && node->numchild == 2))
610    return mpsr_Failure;
611  // get the two args of the value
612  ta = (MPT_Tree_pt *) val->args;
613
614
615  // We get the exponent vector specification first
616  node = ta[1]->node;
617  if (! (NodeCheck(node, MP_CommonMetaOperatorType, MP_ProtoDict,
618                   MP_CopProtoArray) && node->numchild > 0))
619    return mpsr_Failure;
620  // check r->N and reset, if necessary
621  if (mv) 
622  {
623    if (r->N != (int) (node->numchild - 1))
624    {
625      Warn("GetProtoAnnot: Inconsistent NumVars specification");
626      r->N = (node->numchild -1);
627    }
628  }
629  else
630  {
631    if (r->N != (int) node->numchild)
632    {
633      Warn("GetProtoAnnot: Inconsistent NumVars specification");
634      r->N = (node->numchild);
635    }
636  }
637  // check for type of exponent
638  if ((val = MPT_GetProtoTypespec(node)) == NULL)
639    return mpsr_Failure;
640 
641  node = val->node;
642  falser(NodeCheck(node, MP_CommonMetaType, MP_ProtoDict, MP_CmtProtoIMP_Sint32));
643
644  // consider the first arg -- which specify the coeffs
645  val = ta[0];
646  node = val->node;
647  if (node->type == MP_CommonMetaType)
648  {
649    // char 0
650    if (MP_COMMON_T(node->nvalue) == MP_CmtNumberRational &&
651        node->dict == MP_NumberDict)
652    {
653      r->ch = 0;
654      // Hmm ... we should check for the normalized annot
655    }
656    else if (MP_COMMON_T(node->nvalue) == MP_CmtProtoIMP_Uint32 &&
657             node->dict == MP_ProtoDict &&
658             (annot = MPT_FindAnnot(node,MP_NumberDict,MP_AnnotNumberModulos))
659              != NULL)
660    {
661      // char p || GF(p,n)
662      falser(annot->value != NULL &&
663             annot->value->node->type == MP_Uint32Type);
664      r->ch = MP_UINT32_T(annot->value->node->nvalue);
665
666      if (MPT_FindAnnot(annot->value->node,
667                        MP_NumberDict, MP_AnnotNumberIsPrime) == NULL)
668      {
669        // GF(p,n)
670        falser((annot = MPT_FindAnnot(annot->value->node, 129,
671                                  MP_AnnotSingularGalois)) != NULL &&
672           (annot->value != NULL) &&
673           (annot->value->node->type == MP_StringType));
674        r->parameter = (char **)Alloc(sizeof(char *));
675        r->parameter[0] = mstrdup(MP_STRING_T(annot->value->node->nvalue));
676        r->P = 1;
677      }
678    }
679    else if (MP_COMMON_T(node->nvalue) == MP_CmtProtoIMP_Real32 &&
680             node->dict == MP_ProtoDict)
681    {
682      // floats
683      r->ch = -1;
684    }
685    else
686      return mpsr_SetError(mpsr_UnknownCoeffDomain);
687   
688    return mpsr_Success;
689  }
690  else
691  {
692    // alg numbers
693    BOOLEAN mv2;
694    int i;
695
696    // DDP Frac Node check
697    falser(NodeCheck(node, MP_CommonMetaOperatorType, MP_BasicDict,
698                    MP_CopBasicDiv) &&
699           node->numchild == 0);
700    falser((val = MPT_GetProtoTypespec(node)) != NULL);
701    node = val->node;
702    mpsr_assume(node != NULL);
703    falser(NodeCheck(node, MP_CommonMetaOperatorType, MP_PolyDict,
704                     MP_CopPolyDenseDistPoly) &&
705           node->numchild == 0);
706    // GetRingAnnots
707    failr(mpsr_GetRingAnnots(node, subring, mv2));
708    // Check whether the ring can be "coerced" to an algebraic number
709    falser(subring->ch >= 0 &&
710           subring->order[0] == ringorder_lp &&
711           subring->order[2] == 0 &&
712           mv2 == FALSE);
713
714    // Now do the coercion
715    r->ch = (subring->ch == 1 ? 0 : - (subring->ch));
716    r->parameter = (char **) Alloc((subring->N)*sizeof(char*));
717    r->P = subring->N;
718    for (i=0; i < subring->N; i++)
719      r->parameter[i] = mstrdup(subring->names[i]);
720   
721    // everything is ok
722    return mpsr_Success;
723  }
724}
725
726static mpsr_Status_t GetVarNamesAnnot(MPT_Node_pt node, ring r)
727{
728  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyVarNames);
729  short num_vars = 0, N, lb, offset, nc;
730
731  mpsr_assume(r != NULL);
732  N = r->N;
733  r->names = (char **) Alloc(N * sizeof(char *));
734 
735  // fill in varnames from the back
736  if (annot != NULL && annot->value != NULL)
737  {
738    node = annot->value->node;
739    nc = (short) node->numchild;
740    if (NodeCheck(node, MP_CommonOperatorType, MP_ProtoDict, MP_CopProtoArray))
741    {
742      MPT_Tree_pt val = MPT_GetProtoTypespec(node);
743      if (val != NULL &&
744          NodeCheck(val->node, MP_CommonMetaType, MP_ProtoDict,
745                    MP_CmtProtoIMP_Identifier))
746      {
747        MPT_Arg_pt arg_pt = annot->value->args;       
748        lb = min(nc, N);
749        offset = N - (short) nc;
750        if (offset < 0) offset = 0;
751        for (; num_vars < lb; num_vars++)
752          r->names[offset + num_vars] =
753            mstrdup(MP_STRING_T(arg_pt[num_vars]));
754      }
755    }
756    else if (node->type == MP_IdentifierType)
757    {
758      r->names[N-1] = mstrdup(MP_STRING_T(annot->value->node->nvalue));
759      num_vars = 1;
760    }
761  }
762
763  // fill in all remaining varnames
764  if (num_vars < N)
765  {
766    char vn[10];
767    offset = N - num_vars;
768    for (nc = 0; nc < offset; nc++)
769    {
770      sprintf(vn, "x(%d)", nc);
771      r->names[nc] = mstrdup(vn);
772    }
773  }
774
775  if (num_vars < N) return mpsr_Failure;
776  else return mpsr_Success;
777}
778
779static mpsr_Status_t GetOrderingAnnot(MPT_Node_pt node, ring r, BOOLEAN mv)
780{
781  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyOrdering);
782  mpsr_Status_t status = mpsr_Success;
783
784  if (annot == NULL || annot->value == NULL) status = mpsr_Failure;
785
786  if (status == mpsr_Success) node =  annot->value->node;
787
788  // Check for BlockOrdering
789  if (status == mpsr_Success &&
790      NodeCheck(annot->value->node, MP_CommonOperatorType,
791               MP_BasicDict, MP_CopBasicList))
792  {
793    MP_NumChild_t nc = node->numchild, i;
794    MPT_Tree_pt *tarray = (MPT_Tree_pt *) annot->value->args, *tarray2, tree;
795
796    if (! mv) nc += 2; else nc++;
797    r->block0 = (int *) Alloc0(nc*sizeof(int *));
798    r->block1 = (int *) Alloc0(nc*sizeof(int *));
799    r->wvhdl  = (short **) Alloc0(nc*sizeof(short *));
800    r->order  = (int *) Alloc0(nc*sizeof(int *));
801
802    if (! mv)
803    {
804      r->order[nc-2] = ringorder_C;
805      nc = nc - 2;
806    }
807    else
808      nc--;
809
810    for (i=0; i<nc; i++)
811    {
812      tree = tarray[i];
813      if (NodeCheck(tree->node, MP_CommonOperatorType,
814                   MP_BasicDict, MP_CopBasicList) &&
815          tree->node->numchild == 3)
816      {
817        tarray2 = (MPT_Tree_pt *) tree->args;
818        if (GetSimpleOrdering(tarray2[0]->node, r, i) != mpsr_Success ||
819            tarray2[1]->node->type != MP_Uint32Type ||
820            tarray2[2]->node->type != MP_Uint32Type)
821        {
822          status = mpsr_Failure;
823          break;
824        }
825        else
826        {
827          r->block0[i] = MP_SINT32_T(tarray2[1]->node->nvalue);
828          r->block1[i] = MP_SINT32_T(tarray2[2]->node->nvalue);
829        }
830      }
831      else
832      {
833          status = mpsr_Failure;
834          break;
835      }
836    }
837
838    if (status == mpsr_Success) status = mpsr_rSetOrdSgn(r);
839   
840    // Clean up if sth went wrong
841    if (status == mpsr_Failure)
842    {
843      if (mv) nc++;
844      Free(r->block0, nc*sizeof(int *));
845      Free(r->block1, nc*sizeof(int *));
846      Free(r->order, nc*sizeof(int *));
847      Free(r->wvhdl, nc*sizeof(short *));
848    }
849    else
850      return mpsr_Success;
851  }
852
853  // Either Simple Ordering, or sth failed from before
854  r->wvhdl = (short **)Alloc0(3 * sizeof(short *));
855  r->order = (int *) Alloc0(3 * sizeof(int *));
856  r->block0 = (int *)Alloc0(3 * sizeof(int *));
857  r->block1 = (int *)Alloc0(3 * sizeof(int *));
858  r->order[1] = ringorder_C;
859  r->block0[0] = 1;
860  r->block1[0] = r->N;
861
862  // Check for simple Ordering
863  if (status == mpsr_Success)
864  {
865    status = GetSimpleOrdering(node, r, 0);
866  }
867  else
868    r->order[0] = ringorder_unspec;
869 
870  return mpsr_rSetOrdSgn(r);
871}
872
873static mpsr_Status_t GetSimpleOrdering(MPT_Node_pt node, ring r, short i)
874{
875  if (node->type != MP_CommonConstantType)
876    return mpsr_Failure;
877
878  r->order[i] = mpsr_mp2ord(MP_UINT32_T(node->nvalue));
879  if (r->order[i] == ringorder_unspec) return mpsr_Failure;
880
881  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyWeights);
882
883  if (annot == NULL) return mpsr_Success;
884  if (annot->value == NULL) return mpsr_Failure;
885
886  node = annot->value->node;
887  if (r->order[i] == ringorder_M)
888  {
889    if (! NodeCheck(node, MP_CommonOperatorType, MP_MatrixDict,
890                   MP_CopMatrixDenseMatrix))
891      return mpsr_Failure;
892  }
893  else
894  {
895    if (! NodeCheck(node, MP_CommonOperatorType, MP_MatrixDict,
896                   MP_CopMatrixDenseVector))
897      return mpsr_Failure;
898  }
899
900  MPT_Annot_pt annot2 = MPT_FindAnnot(node, MP_ProtoDict, MP_AnnotProtoPrototype);
901
902  if (annot2 == NULL ||
903      ! NodeCheck(annot2->value->node, MP_CommonMetaType, MP_ProtoDict,
904                 MP_CmtProtoIMP_Sint32))
905    return mpsr_Failure;
906
907  MP_Uint32_t nc = node->numchild, j;
908  MP_Sint32_t *w = (MP_Sint32_t *) annot->value->args;
909  short *w2 = (short *) AllocL(nc*sizeof(short));
910 
911  r->wvhdl[i] = w2;
912  for (j = 0; j < nc ; j++)
913    w2[j] = w[j];
914
915  return mpsr_Success;
916}
917
918static mpsr_Status_t GetDefRelsAnnot(MPT_Node_pt node, ring r)
919{
920  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyDefRel);
921  mpsr_leftv mlv;
922  leftv lv;
923  ring r1;
924
925  if (annot == NULL) return mpsr_Success;
926
927  node = annot->value->node;
928  if (node->type != MPT_ExternalDataType) return mpsr_Failure;
929
930  mlv = (mpsr_leftv) annot->value->args;
931  r1 = mlv->r;
932  lv = mlv->lv;
933
934  if (! mpsr_RingEqual(r1, r)) return mpsr_Failure;
935
936  if (lv->rtyp == POLY_CMD)
937  {
938    r->qideal = idInit(1,1);
939    r->qideal->m[0] = (poly) lv->data;
940    lv->data = NULL;
941  }
942  else if (lv->rtyp == IDEAL_CMD)
943  {
944    r->qideal = (ideal) lv->data;
945    lv->data = NULL;
946  }
947  else return mpsr_Failure;
948 
949  return mpsr_Success;
950}
951 
952extern mpsr_Status_t mpsr_rSetOrdSgn(ring r)
953{
954  short i = 0, order;
955  r->OrdSgn = 1;
956
957  while ((order = r->order[i]) != ringorder_no)
958  {
959    if (order == ringorder_ls ||
960        order == ringorder_Ws ||
961        order == ringorder_ws ||
962        order == ringorder_Ds ||
963        order == ringorder_ds)
964    {
965      r->OrdSgn = -1;
966      return mpsr_Success;
967    }
968    if (order == ringorder_M)
969    {
970      int sz = r->block1[i] - r->block0[i] + 1, j, k=0;
971      short *matrix = r->wvhdl[i];
972     
973      while (k < sz)
974      {
975        j = 0;
976        while ((j < sz) && matrix[j*sz+k]==0) j++;
977        if (j>=sz)
978        {
979          Warn("Matrix order not complete");
980          r->OrdSgn = 0;
981          return mpsr_Failure;
982        }
983        else if (matrix[j*sz+k]<0)
984        {
985          r->OrdSgn = -1;
986          return mpsr_Success;
987        }
988        else
989          k++;
990      }
991    }
992    i++;
993  }
994  return mpsr_Success;
995}
996
997#endif
Note: See TracBrowser for help on using the repository browser.