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