/* Given a Grobner basis it returns the "PBW" basis * With -d option, it prints monomials with degree < argument (default=MAXDEG). * With -b option, it prints monomials with lexicog. order < argument (default=all monomials). * */ /* Example of input: %Rack (for my program base) abcde %relations up to degree 7 a*a, b*b, c*c, d*d, e*e, d*c + c*a + b*d + a*b, e*a + c*b + b*e + a*c, e*b + d*e + b*a + a*d, e*c + d*a + c*d + a*e, e*d + d*b + c*e + b*c, b*a*b*a + a*b*a*b, c*a*c - b*c*a - b*a*b + a*b*c, d*b*d - c*d*b - c*b*c + b*c*d, c*b*a - b*c*b - b*a*c + a*c*a, d*b*a + d*a*d - b*a*b - a*d*b, d*a*c - c*b*d - c*a*b - a*d*a - a*c*d, d*a*b + c*d*b + c*b*c - b*d*a - b*c*d - a*b*a, c*b*c*a - c*a*b*c + b*a*c*b - a*c*a*b, c*b*c*b + b*c*b*c, d*a*d*a + a*d*a*d, d*b*c*a - d*a*d*b + c*d*b*c + b*c*b*d + b*c*a*b, d*b*c*b + c*a*b*a + b*a*d*b + b*a*b*c + a*d*b*c + a*b*a*d, d*b*c*d + c*a*d*b + c*a*b*c + b*d*b*c + a*b*d*b, c*a*b*c*a - b*a*b*c*b + a*c*a*b*a + a*b*a*b*c, c*a*b*c*b + c*a*b*a*c - b*c*a*b*a - a*b*a*c*a, c*a*b*a*b + b*a*b*c*b - a*c*a*b*a - a*b*a*b*c, c*a*b*a*c*b - b*a*c*a*b*a - a*b*a*c*a*b, c*a*b*a*c*a*b - b*c*a*b*a*c*a, */ #include #include #include #define MAXSIZE 50 // max dim for V #define MAXGROBNER 800 // max number of grobner relations #define MAXDEG 40 // max degree in grobner relations int cardx; // size of X (basis of V) char rack[MAXSIZE]; // the set X char *leading[MAXGROBNER]; // leading terms of grobner basis int grobnernr; // number of grobner relations int pol[MAXDEG+2]; // Hilbert pol. int md; // max degree for producebasis char hilbert[MAXDEG*MAXSIZE*10]; // Hilbert pol for maple int maxdeg=MAXDEG; // max degree, can be smaller than MAXDEG when -d is used in input char belmt[MAXDEG]; // bound element. The result will be those elements below it, if it is not \0 isinstr(char c, char *str) { int i=0; while ((str[i] != c) && str[i]) i++; if (str[i]) return (i+1); else return (0); } readgrobner(FILE *in) { int samerel; int j,p,k; char c; grobnernr=0; while (1) { while (!isinstr(c=getc(in), rack) && c != EOF) { if (c=='%') while (getc(in) != '\n'); } if (c==EOF) { fclose(in); return(0); } leading[grobnernr]=calloc(maxdeg, sizeof(char)); leading[grobnernr][0]=c; j=1; samerel=1; while (samerel) { while(!isinstr(c=getc(in), rack) && !isinstr(c, "^+-,;")); if (isinstr(c, rack)) { leading[grobnernr][j++]=c; } else { switch (c) { case '^': fscanf(in, "%d", &p); for (k=1; k0; k--) { *(str+k-1) = i % 10 + '0'; i /= 10; } } addstrtostr(char *str, char *add) { while (*str++); str--; while (*str++ = *add++); } deletechars(char *str, int i) { while (*str++); *(str-i-1) = '\0'; } substr(char *a, char *b) { int i, j, la, lb; la=length(a); lb=length(b); for (i=0; i<=lb-la; i++) { for (j=0; jdeg) continue; else { if (substr(leading[i], mon)) return (i+1); } } return(0); } producebasis(char *mon, int deg) { int i,j; char c; if (deg>=maxdeg) return(0); for (i=cardx-1; i>=0; i--) { if (!*belmt && i>=isinstr(*mon, rack)) continue; mon[deg]=rack[i]; if (!iszero(mon, deg+1) && (!*belmt || strcmp(mon, belmt)<0)) { printf("(%2d) %s\n", deg+1, mon); pol[deg+1]++; md=(deg>=md)?deg+1:md; // scanf("%c", &c); mon[deg+2]='\0'; producebasis(mon, deg+1); } if (deg==0) { addstrtostr(hilbert, "("); for (j=0; j