Annotation of OpenXM/src/kan96xx/Kan/Kclass/indeterminate.c, Revision 1.1.1.1
1.1 maekawa 1: /* Kclass/indeterminate.c */
2: /* This file handles indeterminate, tree, recursivePolynomial,
3: polynomialInOneVariable
4: */
5: #include <stdio.h>
6: #include "../datatype.h"
7: #include "../stackm.h"
8: #include "../extern.h"
9: #include "../gradedset.h"
10: #include "../extern2.h"
11: #include "../kclass.h"
12:
13:
14: /* Data conversion function : see KclassDataConversion*/
15: struct object KpoIndeterminate(struct object ob) {
16: struct object rob;
17: struct object *newobp;
18: rob.tag = Sclass;
19: rob.lc.ival = CLASSNAME_indeterminate;
20: newobp = (struct object *) sGC_malloc(sizeof(struct object));
21: if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
22: if (ob.tag != Sdollar) {
23: errorKan1("%s\n","Kclass/indeterminate.c, only String object can be transformed into indeterminate.");
24: }
25: *newobp = ob;
26: rob.rc.voidp = newobp;
27: return(rob);
28: }
29:
30: /* The second constructor. */
31: struct object KnewIndeterminate(char *s) {
32: struct object ob;
33:
34: ob = KpoString(s); /* We do not clone s */
35: return(KpoIndeterminate(ob));
36: }
37:
38:
39: /* Printing function : see fprintClass */
40: void fprintIndeterminate(FILE *fp,struct object op)
41: {
42: printObject(KopIndeterminate(op),0,fp);
43: }
44:
45:
46: /* ---------------------------------------------------- */
47: /* Data conversion function : see KclassDataConversion*/
48: struct object KpoTree(struct object ob) {
49: struct object rob;
50: struct object ob1,ob2,ob3;
51: struct object *newobp;
52: rob.tag = Sclass;
53: rob.lc.ival = CLASSNAME_tree;
54: newobp = (struct object *) sGC_malloc(sizeof(struct object));
55: if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
56: if (ob.tag != Sarray) {
57: errorKan1("%s\n","Kclass/indeterminate.c, only properly formatted list object can be transformed into tree. [name, cdname, arglist].");
58: }
59: if (getoaSize(ob) < 3) {
60: errorKan1("%s\n","Kclass/indeterminate.c, the length must 3 or more than 3. [name, cdname, arglist].");
61: }
62: ob1 = getoa(ob,0); ob2 = getoa(ob,1); ob3 = getoa(ob,2);
63: if (ob1.tag != Sdollar || ob2.tag != Sdollar || ob3.tag != Sarray) {
64: errorKan1("%s\n","Kclass/indeterminate.c, [string name, string cdname, list arglist].");
65: }
66: *newobp = ob;
67: rob.rc.voidp = newobp;
68: return(rob);
69: }
70:
71:
72: /* Printing function : see fprintClass */
73: void fprintTree(FILE *fp,struct object op)
74: {
75: printObject(KopTree(op),0,fp);
76: }
77:
78: int isTreeAdd(struct object ob) {
79: struct object name;
80: if (ob.tag != Sclass) {
81: return(0);
82: }
83: if (ectag(ob) != CLASSNAME_tree) {
84: return(0);
85: }
86: ob = KopTree(ob);
87: if (ob.tag != Sarray) {
88: errorKan1("%s\n","CLASSNAME_tree is broken. Should be array.");
89: }
90: name = getoa(ob,0);
91: if (name.tag != Sdollar) {
92: errorKan1("%s\n","CLASSNAME_tree is broken. Should be string.");
93: }
94: if (strcmp(KopString(name),"add") == 0) {
95: return(1);
96: }else{
97: return(0);
98: }
99: }
100:
101: struct object addTree(struct object ob1, struct object ob2)
102: {
103: struct object rob,aob;
104: struct object ob3,ob4;
105: int i;
106: if (isTreeAdd(ob1) && !isTreeAdd(ob2)) {
107: ob1 = KopTree(ob1);
108: ob3 = getoa(ob1,2);
109: aob = newObjectArray(getoaSize(ob3)+1);
110: for (i=0; i<getoaSize(ob3); i++) {
111: putoa(aob,i,getoa(ob3,i));
112: }
113: putoa(aob,getoaSize(ob3),ob2);
114: }else if (!isTreeAdd(ob1) && isTreeAdd(ob2)) {
115: ob2 = KopTree(ob2);
116: ob3 = getoa(ob2,2);
117: aob = newObjectArray(getoaSize(ob3)+1);
118: putoa(aob,0,ob1);
119: for (i=0; i<getoaSize(ob3); i++) {
120: putoa(aob,1+i,getoa(ob3,i));
121: }
122: }else if (isTreeAdd(ob1) && isTreeAdd(ob2)) {
123: ob1 = KopTree(ob1);
124: ob2 = KopTree(ob2);
125: ob3 = getoa(ob1,2);
126: ob4 = getoa(ob2,2);
127: aob = newObjectArray(getoaSize(ob3)+getoaSize(ob4));
128: for (i=0; i<getoaSize(ob3); i++) {
129: putoa(aob,i,getoa(ob3,i));
130: }
131: for (i=0; i<getoaSize(ob4); i++) {
132: putoa(aob,getoaSize(ob3)+i,getoa(ob4,i));
133: }
134: }else{
135: aob = newObjectArray(2);
136: putoa(aob,0,ob1);
137: putoa(aob,1,ob2);
138: }
139: rob = newObjectArray(3);
140: putoa(rob,0,KpoString("add"));
141: putoa(rob,1,KpoString("Basic"));
142: putoa(rob,2,aob);
143: return(KpoTree(rob));
144: }
145:
146:
147: /*------------------------------------------*/
148:
149: struct object KpoRecursivePolynomial(struct object ob) {
150: struct object rob;
151: struct object *newobp;
152: rob.tag = Sclass;
153: rob.lc.ival = CLASSNAME_recursivePolynomial;
154: newobp = (struct object *) sGC_malloc(sizeof(struct object));
155: if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
156: if (ob.tag != Sarray) {
157: errorKan1("%s\n","Kclass/indeterminate.c, only array object can be transformed into recusivePolynomial.");
158: }
159: *newobp = ob;
160: rob.rc.voidp = newobp;
161: return(rob);
162: }
163:
164: static void printBodyOfRecursivePolynomial(struct object body,
165: struct object vlist, FILE *fp)
166: {
167: int i,j;
168: int k;
169: if (ectag(body) != CLASSNAME_polynomialInOneVariable) {
170: printObject(body,0,fp);
171: return;
172: }
173: body = KopPolynomialInOneVariable(body);
174: if (body.tag != Sarray) {
175: errorKan1("%s\n","Kclass/indeterminate.c, format error for recursive polynomial.");
176: }
177: if (getoaSize(body) == 0) {
178: errorKan1("%s\n","printBodyOfRecursivePolynomial: format error for a recursive polynomial.");
179: }
180: i = KopInteger(getoa(body,0));
181: for (j=1; j<getoaSize(body); j = j+2) {
182: k = KopInteger(getoa(body,j));
183: if (k != 0) {
184: fprintf(fp,"%s",KopString(getoa(vlist,i)));
185: if (k > 1) {
186: fprintf(fp,"^%d ",k);
187: }else if (k == 1) {
188: }else{
189: fprintf(fp,"^(%d) ",k);
190: }
191: fprintf(fp," * ");
192: }
193: fprintf(fp,"(");
194: printBodyOfRecursivePolynomial(getoa(body,j+1),vlist,fp);
195: fprintf(fp,")");
196: if (j != getoaSize(body)-2) {
197: fprintf(fp," + ");
198: }
199: }
200: return;
201: }
202:
203: void fprintRecursivePolynomial(FILE *fp,struct object op)
204: {
205: /* old code
206: printObject(KopRecursivePolynomial(op),0,fp); return;
207: */
208: struct object ob;
209: struct object vlist;
210: struct object body;
211: ob = KopRecursivePolynomial(op);
212: if (ob.tag != Sarray) {
213: printObject(ob,0,fp); return;
214: }
215: if (!isRecursivePolynomial2(op)) {
216: printObject(KopRecursivePolynomial(op),0,fp); return;
217: }
218: vlist = getoa(ob,0);
219: body = getoa(ob,1);
220: printBodyOfRecursivePolynomial(body,vlist,fp);
221: return;
222: }
223:
224: /*------------------------------------------*/
225:
226: struct object KpoPolynomialInOneVariable(struct object ob) {
227: struct object rob;
228: struct object *newobp;
229: rob.tag = Sclass;
230: rob.lc.ival = CLASSNAME_polynomialInOneVariable;
231: newobp = (struct object *) sGC_malloc(sizeof(struct object));
232: if (newobp == NULL) errorKan1("%s\n","Kclass/indeterminate.c, no more memory.");
233: if (ob.tag != Sarray) {
234: errorKan1("%s\n","Kclass/indeterminate.c, only array object can be transformed into polynomialInOneVariable.");
235: }
236: *newobp = ob;
237: rob.rc.voidp = newobp;
238: return(rob);
239: }
240:
241: void fprintPolynomialInOneVariable(FILE *fp,struct object op)
242: {
243: printObject(KopPolynomialInOneVariable(op),0,fp);
244: }
245:
246: struct object polyToRecursivePoly(struct object p) {
247: struct object rob = NullObject;
248: int vx[N0], vd[N0];
249: int i,j,k,n,count;
250: POLY f;
251: struct object vlist,vlist2;
252: struct object ob1,ob2,ob3,ob4;
253: int vn;
254:
255: if (p.tag != Spoly) return(rob);
256: f = KopPOLY(p);
257: if (f == ZERO) {
258: rob = p; return(rob);
259: }
260: /* construct list of variables. */
261: for (i=0; i<N0; i++) {
262: vx[i] = vd[i] = 0;
263: }
264: n = f->m->ringp->n; count = 0;
265: for (i=0; i<n; i++) {
266: if (pDegreeWrtV(f,cxx(1,i,1,f->m->ringp))) {
267: vx[i] = 1; count++;
268: }
269: if (pDegreeWrtV(f,cdd(1,i,1,f->m->ringp))) {
270: vd[i] = 1; count++;
271: }
272: }
273: vlist = newObjectArray(count); k = 0;
274: vlist2 = newObjectArray(count); k = 0;
275: for (i=0; i<n; i++) {
276: if (vd[i]) {
277: putoa(vlist,k,KpoPOLY(cdd(1,i,1,f->m->ringp)));
278: putoa(vlist2,k,KpoString(POLYToString(cdd(1,i,1,f->m->ringp),'*',0)));
279: k++;
280: }
281: }
282: for (i=0; i<n; i++) {
283: if (vx[i]) {
284: putoa(vlist,k,KpoPOLY(cxx(1,i,1,f->m->ringp)));
285: putoa(vlist2,k,KpoString(POLYToString(cxx(1,i,1,f->m->ringp),'*',0)));
286: k++;
287: }
288: }
289: /* printObject(vlist,1,stdout); */
290: if (getoaSize(vlist) == 0) {
291: vn = -1;
292: }else{
293: vn = 0;
294: }
295: ob1 = polyToRecursivePoly2(p,vlist,vn);
296: rob = newObjectArray(2);
297: putoa(rob,0,vlist2); putoa(rob,1,ob1);
298: /* format of rob
299: [ list of variables, poly or universalNumber or yyy to express
300: a recursive polynomial. ]
301: format of yyy = CLASSNAME_polynomialInOneVariable
302: [Sinteger, Sinteger, coeff obj, Sinteger, coeff obj, .....]
303: name of var, exp, coeff, exp, coeff
304: This format is checked by isRecursivePolynomial2().
305: */
306: rob = KpoRecursivePolynomial(rob);
307: if (isRecursivePolynomial2(rob)) {
308: return(rob);
309: }else{
310: errorKan1("%s\n","polyToRecursivePolynomial could not translate this object.");
311: }
312: }
313:
314: static void objectFormatError_ind0(char *s) {
315: char tmp[1024];
316: sprintf(tmp,"polyToRecursivePoly2: object format error for the variable %s",s);
317: errorKan1("%s\n",tmp);
318: }
319:
320: struct object polyToRecursivePoly2(struct object p,struct object vlist, int vn) {
321: struct object rob = NullObject;
322: POLY f;
323: POLY vv;
324: struct object v;
325: struct object c;
326: struct object e;
327: int i;
328:
329:
330: if (p.tag != Spoly) return(rob);
331: f = KopPOLY(p);
332: if (f == ZERO) {
333: rob = p; return(rob);
334: }
335: if (vn < 0 || vn >= getoaSize(vlist)) {
336: return(coeffToObject(f->coeffp));
337: }
338: v = getoa(vlist,vn);
339: if (v.tag != Spoly) objectFormatError_ind0("v");
340: vv = KopPOLY(v);
341: c = parts2(f,vv);
342: e = getoa(c,0); /* exponents. Array of integer. */
343: if (e.tag != Sarray) objectFormatError_ind0("e");
344: c = getoa(c,1); /* coefficients. Array of POLY. */
345: if (c.tag != Sarray) objectFormatError_ind0("c");
346: rob = newObjectArray(getoaSize(e)*2+1);
347:
348: putoa(rob,0,KpoInteger(vn)); /* put the variable number. */
349: for (i=0; i < getoaSize(e); i++) {
350: putoa(rob,1+i*2, getoa(e,i));
351: putoa(rob,1+i*2+1, polyToRecursivePoly2(getoa(c,i),vlist,vn+1));
352: }
353: /* printObject(rob,0,stderr); */
354: return(KpoPolynomialInOneVariable(rob));
355: }
356:
357: static int isRecursivePolynomial2a(struct object ob2, int n) {
358: char *s = "Format error (isRecursivePolynomial2a) : ";
359: struct object tmp;
360: int i;
361: if (ectag(ob2) == CLASSNAME_polynomialInOneVariable) {
362: ob2 = KopPolynomialInOneVariable(ob2);
363: }else if (ob2.tag == Sarray) {
364: fprintf(stderr,"isRecursivePolynomial2, argument is an array.\n");
365: printObject(ob2,0,stderr);
366: fprintf(stderr,"\n");
367: return(0); /* Array must be an error, but other objects are OK. */
368: }else {
369: return(1);
370: }
371: if (ob2.tag != Sarray) {
372: return(1);
373: /* coeff can be any. */
374: }
375: if (getoaSize(ob2) % 2 == 0) {
376: fprintf(stderr,"%s list body. The size of body must be odd.\n",s); printObject(ob2,1,stderr);
377: return(0);
378: }
379: tmp = getoa(ob2,0);
380: if (tmp.tag != Sinteger) {
381: fprintf(stderr,"%s list body. body[0] must be integer.\n",s); printObject(ob2,1,stderr);
382: return(0);
383: }
384: if (KopInteger(tmp) < 0 || KopInteger(tmp) >= n) {
385: fprintf(stderr,"%s list body. body[0] must be integer between 0 and the size of vlist -1.\n",s); printObject(ob2,1,stderr);
386: return(0);
387: }
388: for (i=1; i<getoaSize(ob2); i = i+2) {
389: tmp = getoa(ob2,i);
390: if (tmp.tag != Sinteger) {
391: fprintf(stderr,"%s [list vlist, list body]. body[%d] must be integer.\n",s,i);
392: printObject(ob2,1,stderr);
393: return(0);
394: }
395: }
396: for (i=2; i<getoaSize(ob2); i = i+2) {
397: tmp = getoa(ob2,i);
398: if (ectag(tmp) == CLASSNAME_polynomialInOneVariable) {
399: if (isRecursivePolynomial2a(tmp,n)) {
400: }else{
401: fprintf(stderr,"isRecursivePolynomial2a: entry is not a polynomial in one variable.\n");
402: printObject(tmp,0,stderr); fprintf(stderr,"\n");
403: return(0);
404: }
405: }
406: }
407: return(1);
408: }
409:
410: int isRecursivePolynomial2(struct object ob) {
411: /* This checks only the top level */
412: char *s = "Format error (isRecursivePolynomial2) : ";
413: struct object ob1, ob2,tmp;
414: int i;
415: int n;
416: if (ob.tag != Sclass) return(0);
417: if (ectag(ob) != CLASSNAME_recursivePolynomial) return(0);
418: ob = KopRecursivePolynomial(ob);
419: if (ob.tag != Sarray) {
420: fprintf(stderr,"%s [vlist, body]\n",s); printObject(ob,1,stderr);
421: return(0);
422: }
423: if (getoaSize(ob) != 2) {
424: fprintf(stderr,"%s [vlist, body]. The length must be 2. \n",s);
425: printObject(ob,1,stderr);
426: return(0);
427: }
428: ob1 = getoa(ob,0);
429: ob2 = getoa(ob,1);
430: if (ob1.tag != Sarray) {
431: fprintf(stderr,"%s [list vlist, body].\n",s); printObject(ob,1,stderr);
432: return(0);
433: }
434: n = getoaSize(ob1);
435: for (i=0; i<n; i++) {
436: tmp = getoa(ob1,i);
437: if (tmp.tag != Sdollar) {
438: fprintf(stderr,"%s [list vlist, body]. Element of the vlist must be a string.\n",s); printObject(ob,1,stderr);
439: return(0);
440: }
441: }
442: return(isRecursivePolynomial2a(ob2,n));
443: }
444:
445:
446: struct object coeffToObject(struct coeff *cp) {
447: struct object rob = NullObject;
448: switch(cp->tag) {
449: case INTEGER:
450: rob = KpoInteger( coeffToInt(cp) );
451: return(rob);
452: break;
453:
454: case MP_INTEGER:
455: rob.tag = SuniversalNumber;
456: rob.lc.universalNumber = newUniversalNumber2((cp->val).bigp);
457: return(rob);
458: break;
459:
460: case POLY_COEFF:
461: rob = KpoPOLY((cp->val).f);
462: return(rob);
463: break;
464:
465: default:
466: return(rob);
467: }
468: }
469:
470:
471: struct object recursivePolyToPoly(struct object rp) {
472: struct object rob = NullObject;
473: POLY f;
474: errorKan1("%s\n","recursivePolyToPoly() has not yet been implemented. Use ascii parsing or sm1 macros to reconstruct a polynomial.");
475:
476: return(rob);
477: }
478:
479:
480:
481:
482:
483:
484:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>