source: git/Singular/mpsr_GetMisc.cc @ e06ef94

spielwiese
Last change on this file since e06ef94 was e06ef94, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* added rTest which checks rings if RDEBUG is on * fixed bug in ring-handling of mpsr stuff git-svn-id: file:///usr/local/Singular/svn/trunk@2633 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: mpsr_GetMisc.cc,v 1.10 1998-11-04 17:32:23 obachman Exp $ */
5
6/***************************************************************
7 *
8 * File:       mpsr_GetMisc.cc
9 * Purpose:    Miscellanous routines which are needed by mpsr_Get
10 * Author:     Olaf Bachmann (10/95)
11 *
12 * Change History (most recent first):
13 *
14 ***************************************************************/
15
16#include "mod2.h"
17
18#ifdef HAVE_MPSR
19
20#include"mpsr_Get.h"
21#include "ring.h"
22#include "longalg.h"
23#include "tok.h"
24#include "maps.h"
25#include "lists.h"
26
27BOOLEAN currComplete = FALSE;
28
29static ring rDefault(short ch, char *name);
30static char* GenerateRingName();
31
32
33// use the varname so that they are compatible with the ones generated
34// by GetRingAnnots
35#define MPSR_DEFAULT_VARNAME "x(1)"
36
37// returns some default ring
38int mpsr_rDefault(short ch, char *name, ring &r)
39{
40  // check for currRing
41  if (currRing != NULL && currRing->ch == ch)
42  {
43    int i, n = currRing->N;
44    char **names = currRing->names;
45   
46    for (i=0; i<n; i++)
47    {
48      if (strcmp(names[i], name) == 0)
49      {
50        (currRing->ref)++;
51        r = currRing;
52        return i;
53      }
54    }
55  }
56  r = rDefault(ch, name);
57  return 0;
58}
59
60ring mpsr_rDefault(short ch)
61{
62  if (currRing != NULL && currRing->ch == ch)
63  {
64    (currRing->ref)++;
65    return currRing;
66  }
67  else
68    return rDefault(ch, MPSR_DEFAULT_VARNAME);
69}
70
71static ring rDefault(short ch, char *name)
72{
73  ring r = (ring) Alloc0(sizeof(sip_sring));
74  r->ch = ch;
75  r->N = 1;
76  r->names = (char **) Alloc(sizeof(char *));
77  r->names[0] = mstrdup(name);
78
79  r->wvhdl = (short **)Alloc0(3 * sizeof(short *));
80  /*order: dp,C,0*/
81  r->order = (int *) Alloc(3 * sizeof(int *));
82  r->block0 = (int *)Alloc(3 * sizeof(int *));
83  r->block1 = (int *)Alloc(3 * sizeof(int *));
84  /* ringorder dp for the first block: var 1..3 */
85  r->order[0]  = ringorder_unspec;
86  r->block0[0] = 1;
87  r->block1[0] = 1;
88  /* ringorder C for the second block: no vars */
89  r->order[1]  = ringorder_C;
90  r->block0[1] = 0;
91  r->block1[1] = 0;
92  /* the last block: everything is 0 */
93  r->order[2]  = 0;
94  r->block0[2] = 0;
95  r->block1[2] = 0;
96  rComplete(r);
97  return r;
98}
99
100// returns TRUE, if r1 equals r2
101// FALSE, otherwise
102// Equality is determined componentwise
103BOOLEAN mpsr_RingEqual(ring r1, ring r2)
104{
105  int i, j;
106
107  if (r1 == r2) return 1;
108
109  if (r1 == NULL || r2 == NULL) return 0;
110
111  if ((r1->ch != r2->ch) || (r1->N != r2->N) || (r1->OrdSgn != r2->OrdSgn)
112      || (r1->P != r2->P))
113    return 0;
114
115  for (i=0; i<r1->N; i++)
116    if (strcmp(r1->names[i], r2->names[i])) return 0;
117
118  i=0;
119  while (r1->order[i] != 0)
120  {
121    if (r2->order[i] == 0) return 0;
122    if ((r1->order[i] != r2->order[i]) ||
123        (r1->block0[i] != r2->block0[i]) || (r2->block0[i] != r1->block0[i]))
124      return 0;
125    if (r1->wvhdl[i] != NULL)
126    {
127      if (r2->wvhdl[i] == NULL)
128        return 0;
129      for (j=0; j<r1->block1[i]-r1->block0[i]+1; j++)
130        if (r2->wvhdl[i][j] != r1->wvhdl[i][j])
131          return 0;
132    }
133    else if (r2->wvhdl[i] != NULL) return 0;
134    i++;
135  }
136
137  for (i=0; i<rPar(r1);i++)
138  {
139      if (strcmp(r1->parameter[i], r2->parameter[i])!=0)
140        return 0;
141  }
142
143  if (r1->minpoly != NULL)
144  {
145    if (r2->minpoly == NULL) return 0;
146    mpsr_SetCurrRing(r1, FALSE);
147    if (! naEqual(r1->minpoly, r2->minpoly)) return 0;
148  }
149  else if (r2->minpoly != NULL) return 0;
150
151  if (r1->qideal != NULL)
152  {
153    ideal id1 = r1->qideal, id2 = r2->qideal;
154    int i, n;
155    poly *m1, *m2;
156   
157    if (id2 == NULL) return 0;
158    if ((n = IDELEMS(id1)) != IDELEMS(id2)) return 0;
159
160    mpsr_SetCurrRing(r1, FALSE);
161    m1 = id1->m;
162    m2 = id2->m;
163    for (i=0; i<n; i++)
164      if (! pEqualPolys(m1[i],m2[i])) return 0;
165  }
166  else if (r2->qideal != NULL) return 0;
167
168  return 1;
169}
170
171 
172// returns TRUE, if r1 less or equals r2
173// FALSE, otherwise
174// Less or equal means that r1 is a strong subring of r2
175inline BOOLEAN RingLessEqual(ring r1, ring r2)
176{
177  int i, j;
178
179  if (r1 == r2) return 1;
180
181  if (r1 == NULL) return 1;
182
183  if (r2 == NULL) return 0;
184
185  if ((r1->N > r2->N) || (r1->OrdSgn != r2->OrdSgn) || (r1->P > r2->P))
186    return 0;
187
188  if (r1->ch != 0 && r1->ch != r2->ch) return 0;
189
190  for (i=0, j=0; j<r1->N && i<r2->N; i++)
191    if (strcmp(r1->names[j], r2->names[i]) == 0) j++;
192  if (j < r1->N) return 0;
193
194  // for ordering, suppose that they are only simple orderings
195  if (r1->order[2] != 0 || r2->order[2] != 0 ||
196      (r1->order[0] != r2->order[0] && r1->order[0] != ringorder_unspec) ||
197      r1->order[1] != r2->order[1])
198    return 0;
199 
200  for (i=0; i<r1->P;i++)
201  {
202      if (strcmp(r1->parameter[i], r2->parameter[i])!=0)
203        return 0;
204  }
205  // r1->parameter == NULL && r2->parameter != NULL  is ok
206
207  if (r1->minpoly != NULL)
208  {
209    if (r2->minpoly == NULL) return 0;
210    mpsr_SetCurrRing(r1, FALSE);
211    if (! naEqual(r1->minpoly, r2->minpoly)) return 0;
212  }
213  return 1;
214}
215
216// returns MP_Success and lv2 appended to lv1, both over the same ring,
217// or MP_Failure
218mpsr_Status_t mpsr_MergeLeftv(mpsr_leftv mlv1, mpsr_leftv mlv2)
219{
220  ring r, r1 = mlv1->r, r2 = mlv2->r;
221  leftv lv;
222
223  if (mpsr_RingEqual(r1,r2))
224  {
225    if (r2 != NULL) rKill(r2);
226    r = r1;
227  }
228  else if (RingLessEqual(r1, r2))
229  {
230    r = r2;
231    if (r1 != NULL)
232    {
233      mpsr_MapLeftv(mlv1->lv, r1, r);
234      rKill(r1);
235    }
236  }
237  else if (RingLessEqual(r2, r1))
238  {
239    r = r1;
240    if (r2 != NULL)
241    {
242      mpsr_MapLeftv(mlv2->lv, r2, r);
243      rKill(r2);
244    }
245  }
246  else if (rSum(r1, r2, r) >= 0)
247  {
248    mpsr_MapLeftv(mlv1->lv, r1, r);
249    mpsr_MapLeftv(mlv2->lv, r2, r);
250    rKill(r1);
251    rKill(r2);
252  }
253  else return mpsr_Failure;
254
255  lv = mlv1->lv;
256  while (lv->next != NULL) lv = lv->next;
257 
258  lv->next = mlv2->lv;
259  mlv1->r = r;
260
261#ifdef RDEBUG
262  if (r!= NULL) rTest(r);
263#endif
264  // this is an optimization for the mpsr_rDefault routines
265  currRing = r;
266  return mpsr_Success;
267}
268
269void mpsr_MapLeftv(leftv l, ring from_ring, ring to_ring)
270{
271  int i, n;
272 
273  while (l != NULL)
274  {
275    short typ = l->Typ();
276   
277    switch(typ)
278    {
279        case POLY_CMD:
280        case VECTOR_CMD:
281        {
282          poly p = (poly) l->data;
283          mpsr_SetCurrRing(to_ring, TRUE);
284          l->data = (void *) maIMap(from_ring, (poly) l->data);
285          ppDelete(&p, from_ring);
286          break;
287        }
288
289        case MODUL_CMD:
290        case IDEAL_CMD:
291        case MATRIX_CMD:
292        case MAP_CMD:
293        {
294          ideal id = (ideal) l->Data();
295          n = IDELEMS(id);
296          poly *m = id->m, *m1 = (poly *) Alloc(n*sizeof(poly));
297          mpsr_SetCurrRing(to_ring, TRUE);
298          for (i=0; i<n; i++)
299          {
300            m1[i] = m[i];
301            m[i] = maIMap(from_ring, m[i]);
302          }
303          mpsr_SetCurrRing(from_ring, FALSE);
304          for (i=0; i<n; i++) pDelete(&(m1[i]));
305          Free(m1, n*sizeof(poly));
306          break;
307        }
308         
309        case LIST_CMD:
310        {
311          lists ll = (lists) l->Data();
312          n = ll->nr + 1;
313          for (i=0; i<n; i++) mpsr_MapLeftv(&(ll->m[i]), from_ring, to_ring);
314          break;
315        }
316
317        case COMMAND:
318        {
319          command cmd = (command) l->Data();
320          if (cmd->op == PROC_CMD && cmd->argc == 2)
321            mpsr_MapLeftv(&(cmd->arg2), from_ring, to_ring);
322          else if (cmd->argc > 0)
323          {
324            mpsr_MapLeftv(&(cmd->arg1), from_ring, to_ring);
325            if (cmd->argc > 1)
326            {
327              mpsr_MapLeftv(&(cmd->arg2), from_ring, to_ring);
328              if (cmd->argc > 2)
329                mpsr_MapLeftv(&(cmd->arg3), from_ring, to_ring);
330            }
331          }
332          break;
333        }
334
335        case NUMBER_CMD:
336        {
337          number nn = (number) l->data;
338          mpsr_SetCurrRing(to_ring, TRUE);
339          nSetMap(from_ring->ch, from_ring->parameter, from_ring->P, from_ring->minpoly);
340          l->data = (void *) nMap(nn);
341          mpsr_SetCurrRing(from_ring, FALSE);
342          nDelete(&nn);
343        }
344    }
345    l = l->next;
346  }
347}
348         
349           
350// searches for a ring handle which has a ring which is equal to r
351// if one is found, then this one is set to the new global ring
352// otherwise, a ring name is generated, and a new idhdl is created
353void mpsr_SetCurrRingHdl(ring r)
354{
355  idhdl h = IDROOT, rh = NULL;
356
357  if (r == NULL)
358  {
359    if (currRingHdl != NULL && currRing != IDRING(currRingHdl))
360      mpsr_SetCurrRing(IDRING(currRingHdl), TRUE);
361    return;
362  }
363 
364  rTest(r);
365  // try to find an idhdl which is an equal ring
366  while (h != NULL)
367  {
368    if ((IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD) &&
369        (mpsr_RingEqual(IDRING(h), r)))
370    {
371      // found one
372      rh = h;
373      break;
374    }
375    h = h->next;
376  }
377
378  if (rh != NULL)
379  {
380    // found an idhdl to an equal ring
381    // we better reset currRing, so that rSetHdl does not choke (see
382    // sLastPrinted)
383    if (currRingHdl != NULL && IDRING(currRingHdl) != currRing)
384      mpsr_SetCurrRing(IDRING(currRingHdl), TRUE);
385
386    rSetHdl(rh, TRUE);
387
388    if (currRing != r)
389    {
390      mpsr_assume(r->ref <= 0);
391      rKill(r);
392    }
393  }
394  else
395  {
396    rh = mpsr_InitIdhdl((r->qideal == NULL ? (short) RING_CMD
397                         : (short) QRING_CMD),
398                        (void *) r, GenerateRingName());
399    // reset currRing for reasons explained above
400    if (currRingHdl != NULL) mpsr_SetCurrRing(IDRING(currRingHdl), TRUE);
401    rSetHdl(rh, TRUE);
402    rh->next = IDROOT;
403    IDROOT = rh;
404    r->ref = 0;
405  }
406}
407
408
409int gringcounter = 0;
410char grname[14];
411
412static char* GenerateRingName()
413{
414  sprintf(grname, "mpsr_r%d", gringcounter++);
415  return grname;
416}
417       
418// searches through the Singular namespace for a matching name:
419// the first found is returned together witht the respective ring
420idhdl mpsr_FindIdhdl(char *name, ring &r)
421{
422#ifdef HAVE_NAMESPACES
423  idhdl h = (NSROOT(namespaceroot) != NULL ? namespaceroot->get(name, 0): (idhdl) NULL), h2;
424#else /* HAVE_NAMESPACES */
425  idhdl h = (idroot != NULL ? idroot->get(name, 0): (idhdl) NULL), h2;
426#endif /* HAVE_NAMESPACES */
427  r = NULL;
428 
429  if (h != NULL)
430  {
431    r = NULL;
432    return h;
433  }
434
435  h = IDROOT;
436  while ( h != NULL)
437  {
438    if (IDTYP(h) == RING_CMD || IDTYP(h) == QRING_CMD)
439    {
440      h2 = (IDRING(h)->idroot!=NULL ?IDRING(h)->idroot->get(name, 0) :
441            (idhdl) NULL);
442     
443      if (h2 != NULL)
444      {
445        r = IDRING(h);
446        r->ref++;
447        return h2;
448      }
449    }
450    h = h->next;
451  }
452  return NULL;
453}
454
455
456/***************************************************************
457 *
458 * Stuff which deals with External Data
459 *
460 ***************************************************************/
461
462void mpsr_DeleteExternalData(MPT_ExternalData_t edata)
463{
464  mpsr_leftv mlv = (mpsr_leftv) edata;
465
466  if (edata != NULL)
467  {
468    if (mlv->r != NULL) mpsr_SetCurrRing(mlv->r, FALSE);
469    if (mlv->lv != NULL)
470    {
471      mlv->lv->CleanUp();
472      Free(mlv->lv, sizeof(sleftv));
473    }
474    if (mlv->r != NULL) rKill(mlv->r);
475  }
476  Free(mlv, sizeof(mpsr_sleftv));
477}
478
479void mpsr_CopyExternalData(MPT_ExternalData_t *dest,
480                           MPT_ExternalData_t src)
481{
482  mpsr_leftv slv = (mpsr_leftv) src, dlv;
483
484  if (slv != NULL)
485  {
486    dlv = (mpsr_leftv) Alloc0(sizeof(mpsr_sleftv));
487    dlv->r = rCopy(slv->r);
488    dlv->lv = (leftv) Alloc0(sizeof(sleftv));
489    if (slv->lv != NULL) dlv->lv->Copy(slv->lv);
490    else dlv->lv = NULL;
491
492    *dest = (MPT_ExternalData_t) dlv;
493  }
494  else
495    *dest = NULL;
496}
497
498/***************************************************************
499 *
500 * mpsr initialization
501 *
502 ***************************************************************/
503
504#ifdef MDEBUG
505void * mpAllocBlock( size_t t)
506{
507  return mmDBAllocBlock(t,"mp",0);
508}
509void mpFreeBlock( void* a, size_t t)
510{
511  mmDBFreeBlock(a,t,"mp",0);
512}
513
514void * mpAlloc( size_t t)
515{
516  return mmDBAlloc(t,"mp",0);
517}
518void mpFree(void* a)
519{
520  mmDBFree(a,"mp",0);
521}
522#endif
523
524void mpsr_Init()
525{
526  // memory management functions of MP (and MPT)
527#ifndef MDEBUG
528  IMP_RawMemAllocFnc = mmAlloc;
529  IMP_RawMemFreeFnc = mmFree;
530  IMP_MemAllocFnc = mmAllocBlock;
531  IMP_MemFreeFnc = mmFreeBlock;
532#else
533  IMP_RawMemAllocFnc = mpAlloc;
534  IMP_RawMemFreeFnc = mpFree;
535  IMP_MemAllocFnc = mpAllocBlock;
536  IMP_MemFreeFnc = mpFreeBlock;
537#endif
538
539  // Init of the MPT External Data functions
540  MPT_GetExternalData = mpsr_GetExternalData;
541  MPT_DeleteExternalData = mpsr_DeleteExternalData;
542
543#ifdef  PARI_BIGINT_TEST
544  init(4000000, 2);
545#endif 
546}
547
548#ifdef MPSR_DEBUG
549// this is just a dummy function, where we can set a debugger breakpoint
550void mpsr_Break()
551{
552  Werror("mpsr_Error");
553}
554#endif
555
556#endif // HAVE_MPSR
Note: See TracBrowser for help on using the repository browser.