source: git/Singular/mpsr_GetPoly.cc @ 4a8d95

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