source: git/Singular/mpsr_GetPoly.cc @ 400884

spielwiese
Last change on this file since 400884 was 5615cd9, checked in by Olaf Bachmann <obachman@…>, 27 years ago
* small changes git-svn-id: file:///usr/local/Singular/svn/trunk@465 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 24.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/* $Id: mpsr_GetPoly.cc,v 1.8 1997-06-30 17:04:46 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    *x =  (number) Alloc0(sizeof(rnumber));
244    y = (number) *x;
245    y->s = 3;
246    gnum = &(y->z);
247    mpz_init(gnum);
248    mp_failr(IMP_MyGetApInt(link, (MP_ApInt_t *) &gnum));
249  }
250  // fraction of numbers
251  else if (node == MP_CommonOperatorType &&
252           dict== MP_BasicDict &&
253           cvalue == MP_CopBasicDiv)
254  {
255    if (num_annots > 0)
256    {
257      mpt_failr(MPT_SkipAnnots(link, num_annots, &req));
258      if (req) return mpsr_SetError(mpsr_ReqAnnotSkip);
259    }
260    *x =  (number) Alloc0(sizeof(rnumber));
261    y = (number) *x;
262    y->s = 1;
263    failr(GetApInt(link, &(y->z)));
264    return GetApInt(link, &(y->n));
265  }
266  // check for some more esoteric cases
267  else if (node == MP_Uint8Type)
268    *x = nlInit(cvalue);
269  else if (node == MP_Sint8Type)
270    // be careful -- need to handle the value "-2", for example
271    *x = nlInit((int) ((MP_Sint8_t) cvalue));
272  else if (node == MP_Uint32Type)
273  {
274    MP_Uint32_t ui;
275    mp_failr(IMP_GetUint32(link, &ui));
276    // check whether u_int can be casted safely to int
277    if (ui < INT_MAX)
278      *x = nlInit(i);
279    else
280    {
281      // otherwise, make an apint out of it
282      *x =  (number) Alloc0(sizeof(rnumber));
283      y = (number) *x;
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;
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  exp = &(a->e[0]);
323  mp_failr(IMP_GetSint32Vector(link, (MP_Sint32_t **) &exp, naNumbOfPar));
324
325  for (j=1; j<nm; j++)
326  {
327    a->ne = napNew();
328    a = a->ne;
329    failr(GetAlgNumberNumber(link, &(a->ko)));
330    exp = &(a->e[0]);
331    mp_failr(IMP_GetSint32Vector(link, (MP_Sint32_t **) &exp, naNumbOfPar));
332  }
333  a->ne = NULL;
334
335  return mpsr_Success;
336}
337
338static mpsr_Status_t GetAlgNumber(MP_Link_pt link, number *a)
339{
340  lnumber b;
341  MP_Uint32_t ut;
342
343  // Get the union tag
344  mp_failr(IMP_GetUint32(link, &ut));
345  if (ut == 0)
346  {
347    *a = NULL;
348    return mpsr_Success;
349  }
350  else if (ut == 1 || ut == 2)
351  {
352    // single number
353    b = (lnumber) Alloc0(sizeof(rnumber));
354    *a = (number) b;
355    failr(GetAlgPoly(link, &(b->z)));
356    if (ut == 2)
357      return GetAlgPoly(link, &(b->n));
358    else
359      return mpsr_Success;
360  }
361  else
362    return mpsr_SetError(mpsr_WrongUnionDiscriminator);
363}
364
365/***************************************************************
366 *
367 *  Getting polys
368 *
369 ***************************************************************/
370mpsr_Status_t mpsr_GetPoly(MP_Link_pt link, poly &p, MP_Uint32_t nmon,
371                         ring cring)
372{
373  poly pp;
374  MP_Sint32_t i;
375  MP_Uint32_t j;
376  short *exp;
377
378  if (! IsCurrGetRing(cring))
379    SetGetFuncs(cring);
380 
381  if (nmon == 0)
382  {
383    p = NULL;
384    return mpsr_Success;
385  }
386 
387  pp = pNew();
388  p = pp;
389  failr(GetCoeff(link, &(pp->coef)));
390  if (gNvars > 1)
391  {
392    mp_failr(IMP_GetSint32Vector(link, &gTa, gNvars));
393    pp->exp[0] = 0;
394    for (i=0, exp=&(pp->exp[1]); i<gNvars; i++)
395      exp[i] = (short) gTa[i];
396    pSetm(pp);
397
398    for (j=1; j<nmon; j++)
399    {
400      pp->next = pNew();
401      pp = pp->next;
402      failr(GetCoeff(link, &(pp->coef)));
403      mp_failr(IMP_GetSint32Vector(link, &gTa, gNvars));
404      pp->exp[0] = 0;
405      for (i=0, exp=&(pp->exp[1]); i<gNvars; i++)
406        exp[i] = (short) gTa[i];
407      pSetm(pp);
408    }
409  }
410  else
411  {
412    mp_failr(IMP_GetSint32(link, &i));
413    pp->exp[0] = 0;
414    pp->exp[1] = (short) i;
415    pSetm(pp);
416   
417    for (j=1; j<nmon; j++)
418    {
419      pp->next = pNew();
420      pp = pp->next;
421      failr(GetCoeff(link, &(pp->coef)));
422      mp_failr(IMP_GetSint32(link, &i));
423      pp->exp[0] = 0;
424      pp->exp[1] = (short) i;
425      pSetm(pp);
426    }
427  }
428
429  pp->next = NULL;
430
431  pTest(p);
432  return mpsr_Success;
433}
434
435mpsr_Status_t mpsr_GetPolyVector(MP_Link_pt link, poly &p, MP_Uint32_t nmon,
436                          ring cring)
437{
438  poly pp;
439  MP_Sint32_t i, n1;
440  MP_Uint32_t j;
441  short *exp;
442
443  if (!IsCurrGetRing(cring))
444    SetGetFuncs(cring);
445 
446  n1 = gNvars + 1;
447  if (nmon == 0)
448  {
449    p = NULL;
450    return mpsr_Success;
451  }
452 
453  pp = pNew();
454  p = pp;
455  failr(GetCoeff(link, &(pp->coef)));
456  if (gNvars > 1)
457  {
458    mp_failr(IMP_GetSint32Vector(link, &gTa, n1));
459    pp->exp[0] = 0;
460    for (i=0, exp=&(pp->exp[0]); i<n1; i++)
461      exp[i] = (short) gTa[i];
462    pSetm(pp);
463
464    for (j=1; j<nmon; j++)
465    {
466      pp->next = pNew();
467      pp = pp->next;
468      failr(GetCoeff(link, &(pp->coef)));
469      mp_failr(IMP_GetSint32Vector(link, &gTa, n1));
470      pp->exp[0] = 0;
471      for (i=0, exp=&(pp->exp[0]); i<n1; i++)
472        exp[i] = (short) gTa[i];
473      pSetm(pp);
474    }
475  }
476  else
477  {
478    mp_failr(IMP_GetSint32(link, &i));
479    pp->exp[0] = (short) i;
480    mp_failr(IMP_GetSint32(link, &i));
481    pp->exp[1] = (short) i;
482    pSetm(pp);
483   
484    for (j=1; j<nmon; j++)
485    {
486      pp->next = pNew();
487      pp = pp->next;
488      failr(GetCoeff(link, &(pp->coef)));
489      mp_failr(IMP_GetSint32(link, &i));
490      pp->exp[0] = (short) i;
491      mp_failr(IMP_GetSint32(link, &i));
492      pp->exp[1] = (short) i;
493      pSetm(pp);
494    }
495  }
496  pp->next = NULL;
497
498  pTest(p);
499  return mpsr_Success;
500}
501
502/***************************************************************
503 *
504 *  The Getting annotation buisness
505 *
506 ***************************************************************/
507#define falser(x)                               \
508do                                              \
509{                                               \
510  if (!(x)) return mpsr_Failure;                   \
511}                                               \
512while (0)
513
514// We assume that the node is that of a DDP: This returns
515// MP_Succcess, if annots of node can be used to construct a
516// Singular ring (in which case r is the respective ring) or,
517// MP_Failure, if not
518mpsr_Status_t mpsr_GetRingAnnots(MPT_Node_pt node, ring &r, BOOLEAN &mv)
519{
520  sip_sring r1, *subring;
521  poly minpoly = NULL;
522
523  memset(&r1, 0, sizeof(sip_sring));
524
525  r = NULL;
526  if (MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyModuleVector) != NULL)
527    mv = 1;
528  else
529    mv = 0;
530
531  // sets r->N
532  if (GetVarNumberAnnot(node, &r1, mv) != mpsr_Success)
533    Warn("GetVarNumberAnnot: using the one found in the prototype");
534
535  // sets r->char and r->minpoly, r->parameter; if necessary
536  failr(GetProtoTypeAnnot(node, &r1, mv, subring));
537
538  // if we are still here, then we are successful in constructing the ring
539  r = (ring) Alloc(sizeof(sip_sring));
540  memcpy(r, &r1, sizeof(sip_sring));
541
542  if (GetVarNamesAnnot(node, r) != mpsr_Success)
543    Warn("GetVarNamesAnnot: using default variable names");
544
545  if (GetOrderingAnnot(node,r, mv) != mpsr_Success)
546    Warn("GetOrderingAnnot: using unspec ordering");
547
548  if (GetDefRelsAnnot(node, r) != mpsr_Success)
549    Warn("GetDefRelsAnnot: using no defining relations");
550
551  // check on whether or not I have to set a minpoly
552  if (subring != NULL)
553  {
554    if ((subring->qideal != NULL) &&
555        ((minpoly = subring->qideal->m[0]) != NULL))
556    {
557      mpsr_SetCurrRing(r, TRUE);
558      minpoly = maIMap(subring, minpoly);
559      r->minpoly = minpoly->coef;
560      pFree1(minpoly);
561    }
562    rKill(subring);
563  }
564   
565  return mpsr_Success;
566}
567
568
569static mpsr_Status_t GetVarNumberAnnot(MPT_Node_pt node, ring r, BOOLEAN mv)
570{
571  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyVarNumber);
572
573  if (annot != NULL) 
574  {
575    if (annot->value != NULL && annot->value->node->type == MP_Uint32Type)
576    {
577      // Hm.. should check that r->N is not too big for Singular
578      r->N = (short) MP_UINT32_T(annot->value->node->nvalue);
579      if (mv) (r->N)--;
580      return mpsr_Success;
581    }
582  }
583  return mpsr_Failure;
584}
585
586         
587static mpsr_Status_t GetProtoTypeAnnot(MPT_Node_pt node, ring r, BOOLEAN mv,
588                                     ring &subring)
589{
590  MPT_Annot_pt annot = NULL;
591  MPT_Tree_pt  val;
592  MPT_Tree_pt  *ta;
593
594  subring = NULL;
595 
596  // look for prototype annot
597  if ((val = MPT_GetProtoTypespec(node)) == NULL)
598    return mpsr_Failure;
599
600  // check value of annot
601  node = val->node;
602  if (! (NodeCheck(node, MP_CommonOperatorType, MP_ProtoDict,
603                   MP_CopProtoStruct) && node->numchild == 2))
604    return mpsr_Failure;
605  // get the two args of the value
606  ta = (MPT_Tree_pt *) val->args;
607
608
609  // We get the exponent vector specification first
610  node = ta[1]->node;
611  if (! (NodeCheck(node, MP_CommonMetaOperatorType, MP_ProtoDict,
612                   MP_CopProtoArray) && node->numchild > 0))
613    return mpsr_Failure;
614  // check r->N and reset, if necessary
615  if (mv) 
616  {
617    if (r->N != (int) (node->numchild - 1))
618    {
619      Warn("GetProtoAnnot: Inconsistent NumVars specification");
620      r->N = (node->numchild -1);
621    }
622  }
623  else
624  {
625    if (r->N != (int) node->numchild)
626    {
627      Warn("GetProtoAnnot: Inconsistent NumVars specification");
628      r->N = (node->numchild);
629    }
630  }
631  // check for type of exponent
632  if ((val = MPT_GetProtoTypespec(node)) == NULL)
633    return mpsr_Failure;
634 
635  node = val->node;
636  falser(NodeCheck(node, MP_CommonMetaType, MP_ProtoDict, MP_CmtProtoIMP_Sint32));
637
638  // consider the first arg -- which specify the coeffs
639  val = ta[0];
640  node = val->node;
641  if (node->type == MP_CommonMetaType)
642  {
643    // char 0
644    if (MP_COMMON_T(node->nvalue) == MP_CmtNumberRational &&
645        node->dict == MP_NumberDict)
646    {
647      r->ch = 0;
648      // Hmm ... we should check for the normalized annot
649    }
650    else if (MP_COMMON_T(node->nvalue) == MP_CmtProtoIMP_Uint32 &&
651             node->dict == MP_ProtoDict &&
652             (annot = MPT_FindAnnot(node,MP_NumberDict,MP_AnnotNumberModulos))
653              != NULL)
654    {
655      // char p || GF(p,n)
656      falser(annot->value != NULL &&
657             annot->value->node->type == MP_Uint32Type);
658      r->ch = MP_UINT32_T(annot->value->node->nvalue);
659
660      if (MPT_FindAnnot(annot->value->node,
661                        MP_NumberDict, MP_AnnotNumberIsPrime) == NULL)
662      {
663        // GF(p,n)
664        falser((annot = MPT_FindAnnot(annot->value->node, 129,
665                                  MP_AnnotSingularGalois)) != NULL &&
666           (annot->value != NULL) &&
667           (annot->value->node->type == MP_StringType));
668        r->parameter = (char **)Alloc(sizeof(char *));
669        r->parameter[0] = mstrdup(MP_STRING_T(annot->value->node->nvalue));
670        r->P = 1;
671      }
672    }
673    else if (MP_COMMON_T(node->nvalue) == MP_CmtProtoIMP_Real32 &&
674             node->dict == MP_ProtoDict)
675    {
676      // floats
677      r->ch = -1;
678    }
679    else
680      return mpsr_SetError(mpsr_UnknownCoeffDomain);
681   
682    return mpsr_Success;
683  }
684  else
685  {
686    // alg numbers
687    BOOLEAN mv2;
688    int i;
689
690    // DDP Frac Node check
691    falser(NodeCheck(node, MP_CommonMetaOperatorType, MP_BasicDict,
692                    MP_CopBasicDiv) &&
693           node->numchild == 0);
694    falser((val = MPT_GetProtoTypespec(node)) != NULL);
695    node = val->node;
696    mpsr_assume(node != NULL);
697    falser(NodeCheck(node, MP_CommonMetaOperatorType, MP_PolyDict,
698                     MP_CopPolyDenseDistPoly) &&
699           node->numchild == 0);
700    // GetRingAnnots
701    failr(mpsr_GetRingAnnots(node, subring, mv2));
702    // Check whether the ring can be "coerced" to an algebraic number
703    falser(subring->ch >= 0 &&
704           subring->order[0] == ringorder_lp &&
705           subring->order[2] == 0 &&
706           mv2 == FALSE);
707
708    // Now do the coercion
709    r->ch = (subring->ch == 1 ? 0 : - (subring->ch));
710    r->parameter = (char **) Alloc((subring->N)*sizeof(char*));
711    r->P = subring->N;
712    for (i=0; i < subring->N; i++)
713      r->parameter[i] = mstrdup(subring->names[i]);
714   
715    // everything is ok
716    return mpsr_Success;
717  }
718}
719
720static mpsr_Status_t GetVarNamesAnnot(MPT_Node_pt node, ring r)
721{
722  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyVarNames);
723  short num_vars = 0, N, lb, offset, nc;
724
725  mpsr_assume(r != NULL);
726  N = r->N;
727  r->names = (char **) Alloc(N * sizeof(char *));
728 
729  // fill in varnames from the back
730  if (annot != NULL && annot->value != NULL)
731  {
732    node = annot->value->node;
733    nc = (short) node->numchild;
734    if (NodeCheck(node, MP_CommonOperatorType, MP_ProtoDict, MP_CopProtoArray))
735    {
736      MPT_Tree_pt val = MPT_GetProtoTypespec(node);
737      if (val != NULL &&
738          NodeCheck(val->node, MP_CommonMetaType, MP_ProtoDict,
739                    MP_CmtProtoIMP_Identifier))
740      {
741        MPT_Arg_pt arg_pt = annot->value->args;       
742        lb = min(nc, N);
743        offset = N - (short) nc;
744        if (offset < 0) offset = 0;
745        for (; num_vars < lb; num_vars++)
746          r->names[offset + num_vars] =
747            mstrdup(MP_STRING_T(arg_pt[num_vars]));
748      }
749    }
750    else if (node->type == MP_IdentifierType)
751    {
752      r->names[N-1] = mstrdup(MP_STRING_T(annot->value->node->nvalue));
753      num_vars = 1;
754    }
755  }
756
757  // fill in all remaining varnames
758  if (num_vars < N)
759  {
760    char vn[10];
761    offset = N - num_vars;
762    for (nc = 0; nc < offset; nc++)
763    {
764      sprintf(vn, "x(%d)", nc);
765      r->names[nc] = mstrdup(vn);
766    }
767  }
768
769  if (num_vars < N) return mpsr_Failure;
770  else return mpsr_Success;
771}
772
773static mpsr_Status_t GetOrderingAnnot(MPT_Node_pt node, ring r, BOOLEAN mv)
774{
775  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyOrdering);
776  mpsr_Status_t status = mpsr_Success;
777
778  if (annot == NULL || annot->value == NULL) status = mpsr_Failure;
779
780  if (status == mpsr_Success) node =  annot->value->node;
781
782  // Check for BlockOrdering
783  if (status == mpsr_Success &&
784      NodeCheck(annot->value->node, MP_CommonOperatorType,
785               MP_BasicDict, MP_CopBasicList))
786  {
787    MP_NumChild_t nc = node->numchild, i;
788    MPT_Tree_pt *tarray = (MPT_Tree_pt *) annot->value->args, *tarray2, tree;
789
790    if (! mv) nc += 2; else nc++;
791    r->block0 = (int *) Alloc0(nc*sizeof(int *));
792    r->block1 = (int *) Alloc0(nc*sizeof(int *));
793    r->wvhdl  = (short **) Alloc0(nc*sizeof(short *));
794    r->order  = (int *) Alloc0(nc*sizeof(int *));
795
796    if (! mv)
797    {
798      r->order[nc-2] = ringorder_C;
799      nc = nc - 2;
800    }
801    else
802      nc--;
803
804    for (i=0; i<nc; i++)
805    {
806      tree = tarray[i];
807      if (NodeCheck(tree->node, MP_CommonOperatorType,
808                   MP_BasicDict, MP_CopBasicList) &&
809          tree->node->numchild == 3)
810      {
811        tarray2 = (MPT_Tree_pt *) tree->args;
812        if (GetSimpleOrdering(tarray2[0]->node, r, i) != mpsr_Success ||
813            tarray2[1]->node->type != MP_Uint32Type ||
814            tarray2[2]->node->type != MP_Uint32Type)
815        {
816          status = mpsr_Failure;
817          break;
818        }
819        else
820        {
821          r->block0[i] = MP_SINT32_T(tarray2[1]->node->nvalue);
822          r->block1[i] = MP_SINT32_T(tarray2[2]->node->nvalue);
823        }
824      }
825      else
826      {
827          status = mpsr_Failure;
828          break;
829      }
830    }
831
832    if (status == mpsr_Success) status = mpsr_rSetOrdSgn(r);
833   
834    // Clean up if sth went wrong
835    if (status == mpsr_Failure)
836    {
837      if (mv) nc++;
838      Free(r->block0, nc*sizeof(int *));
839      Free(r->block1, nc*sizeof(int *));
840      Free(r->order, nc*sizeof(int *));
841      Free(r->wvhdl, nc*sizeof(short *));
842    }
843    else
844      return mpsr_Success;
845  }
846
847  // Either Simple Ordering, or sth failed from before
848  r->wvhdl = (short **)Alloc0(3 * sizeof(short *));
849  r->order = (int *) Alloc0(3 * sizeof(int *));
850  r->block0 = (int *)Alloc0(3 * sizeof(int *));
851  r->block1 = (int *)Alloc0(3 * sizeof(int *));
852  r->order[1] = ringorder_C;
853  r->block0[0] = 1;
854  r->block1[0] = r->N;
855
856  // Check for simple Ordering
857  if (status == mpsr_Success)
858  {
859    status = GetSimpleOrdering(node, r, 0);
860  }
861  else
862    r->order[0] = ringorder_unspec;
863 
864  return mpsr_rSetOrdSgn(r);
865}
866
867static mpsr_Status_t GetSimpleOrdering(MPT_Node_pt node, ring r, short i)
868{
869  if (node->type != MP_CommonConstantType)
870    return mpsr_Failure;
871
872  r->order[i] = mpsr_mp2ord(MP_UINT32_T(node->nvalue));
873  if (r->order[i] == ringorder_unspec) return mpsr_Failure;
874
875  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyWeights);
876
877  if (annot == NULL) return mpsr_Success;
878  if (annot->value == NULL) return mpsr_Failure;
879
880  node = annot->value->node;
881  if (r->order[i] == ringorder_M)
882  {
883    if (! NodeCheck(node, MP_CommonOperatorType, MP_MatrixDict,
884                   MP_CopMatrixDenseMatrix))
885      return mpsr_Failure;
886  }
887  else
888  {
889    if (! NodeCheck(node, MP_CommonOperatorType, MP_MatrixDict,
890                   MP_CopMatrixDenseVector))
891      return mpsr_Failure;
892  }
893
894  MPT_Annot_pt annot2 = MPT_FindAnnot(node, MP_ProtoDict, MP_AnnotProtoPrototype);
895
896  if (annot2 == NULL ||
897      ! NodeCheck(annot2->value->node, MP_CommonMetaType, MP_ProtoDict,
898                 MP_CmtProtoIMP_Sint32))
899    return mpsr_Failure;
900
901  MP_Uint32_t nc = node->numchild, j;
902  MP_Sint32_t *w = (MP_Sint32_t *) annot->value->args;
903  short *w2 = (short *) AllocL(nc*sizeof(short));
904 
905  r->wvhdl[i] = w2;
906  for (j = 0; j < nc ; j++)
907    w2[j] = w[j];
908
909  return mpsr_Success;
910}
911
912static mpsr_Status_t GetDefRelsAnnot(MPT_Node_pt node, ring r)
913{
914  MPT_Annot_pt annot = MPT_FindAnnot(node, MP_PolyDict, MP_AnnotPolyDefRel);
915  mpsr_leftv mlv;
916  leftv lv;
917  ring r1;
918
919  if (annot == NULL) return mpsr_Success;
920
921  node = annot->value->node;
922  if (node->type != MPT_ExternalDataType) return mpsr_Failure;
923
924  mlv = (mpsr_leftv) annot->value->args;
925  r1 = mlv->r;
926  lv = mlv->lv;
927
928  if (! mpsr_RingEqual(r1, r)) return mpsr_Failure;
929
930  if (lv->rtyp == POLY_CMD)
931  {
932    r->qideal = idInit(1,1);
933    r->qideal->m[0] = (poly) lv->data;
934    lv->data = NULL;
935  }
936  else if (lv->rtyp == IDEAL_CMD)
937  {
938    r->qideal = (ideal) lv->data;
939    lv->data = NULL;
940  }
941  else return mpsr_Failure;
942 
943  return mpsr_Success;
944}
945 
946extern mpsr_Status_t mpsr_rSetOrdSgn(ring r)
947{
948  short i = 0, order;
949  r->OrdSgn = 1;
950
951  while ((order = r->order[i]) != ringorder_no)
952  {
953    if (order == ringorder_ls ||
954        order == ringorder_Ws ||
955        order == ringorder_ws ||
956        order == ringorder_Ds ||
957        order == ringorder_ds)
958    {
959      r->OrdSgn = -1;
960      return mpsr_Success;
961    }
962    if (order == ringorder_M)
963    {
964      int sz = r->block1[i] - r->block0[i] + 1, j, k=0;
965      short *matrix = r->wvhdl[i];
966     
967      while (k < sz)
968      {
969        j = 0;
970        while ((j < sz) && matrix[j*sz+k]==0) j++;
971        if (j>=sz)
972        {
973          Warn("Matrix order not complete");
974          r->OrdSgn = 0;
975          return mpsr_Failure;
976        }
977        else if (matrix[j*sz+k]<0)
978        {
979          r->OrdSgn = -1;
980          return mpsr_Success;
981        }
982        else
983          k++;
984      }
985    }
986    i++;
987  }
988  return mpsr_Success;
989}
990
991#endif
Note: See TracBrowser for help on using the repository browser.