Annotation of OpenXM/src/kan96xx/Kan/Kclass/indeterminate.c, Revision 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>