source: git/Singular/mpsr_GetPoly.cc @ 82716e

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