From 4fc923247e286f73ff873f5562a1d30f0316348f Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Sun, 27 Mar 2022 21:01:31 -0400 Subject: more idiomaticization --- big.c | 432 +++++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 270 insertions(+), 162 deletions(-) diff --git a/big.c b/big.c index 4b20d04..255c15c 100644 --- a/big.c +++ b/big.c @@ -15,7 +15,7 @@ #include /* contains remainder from last call to longdiv or shortdiv */ -word b_rem; +static word b_rem; extern char *dicp; @@ -43,69 +43,73 @@ void bigsetup(void) int isnat(word x) { - return (tag[x] == INT && poz(x)); + return (tag[x] == INT && big_is_positive(x)); } /* store C long long as mira bigint */ word sto_int(long long i) { - word s, x; + word s = 0; + if (i < 0) { - s = SIGNBIT, i = -i; - } else { - s = 0; + s = SIGNBIT; + i = -i; } - x = make(INT, (s | i) & MAXDIGIT, 0); - if (i >>= DIGITWIDTH) { - word *p = &rest(x); - *p = make(INT, i & MAXDIGIT, 0), p = &rest(*p); - while (i >>= DIGITWIDTH) { - *p = make(INT, i & MAXDIGIT, 0), p = &rest(*p); - } + + word x = make(INT, (s | i) & MAXDIGIT, 0); + + for (word *p = &rest(x); i >>= DIGITWIDTH; p = &rest(*p)) { + *p = make(INT, i & MAXDIGIT, 0); } - return (x); + + return x; } /* mira bigint to C long long */ long long get_int(word x) { long long n = digit0(x); - word sign = neg(x); + word sign = big_is_negative(x); + if (!(x = rest(x))) { return (sign ? -n : n); } - word w = DIGITWIDTH; - while (x && w < 60) { - n += (long long)digit(x) << w, w += DIGITWIDTH, x = rest(x); + + for (word w = DIGITWIDTH; x && w < 60; w += DIGITWIDTH) { + n += (long long)digit(x) << w; + x = rest(x); } + if (x) { n = maxval; /* overflow, return large value */ } + return (sign ? -n : n); } word bignegate(word x) { if (bigzero(x)) { - return (x); + return x; } - return (make - (INT, hd[x] & SIGNBIT ? hd[x] & MAXDIGIT : SIGNBIT | hd[x], tl[x])); + return make(INT, (hd[x] & SIGNBIT) ? (hd[x] & MAXDIGIT) : (SIGNBIT | hd[x]), + tl[x]); } word bigplus(word x, word y) { - if (poz(x)) { - if (poz(y)) { + if (big_is_positive(x)) { + if (big_is_positive(y)) { return (big_plus(x, y, 0)); } else { return (big_sub(x, y)); } - } else if (poz(y)) { + + } else if (big_is_positive(y)) { return (big_sub(y, x)); - } else { - return (big_plus(x, y, SIGNBIT)); /* both negative */ } + + return (big_plus(x, y, SIGNBIT)); /* both negative */ } /* ignore input signs, treat x,y as positive */ @@ -117,6 +121,7 @@ word big_plus(word x, word y, int signbit) word *z = &rest(r); /* pointer to rest of result */ x = rest(x); y = rest(y); + while (x && y) { /* this loop has been unwrapped once, see above */ d = carry + digit(x) + digit(y); carry = ((d & IBASE) != 0); @@ -125,9 +130,11 @@ word big_plus(word x, word y, int signbit) y = rest(y); z = &rest(*z); } + if (y) { x = y; /* by convention x is the longer one */ } + while (x) { d = carry + digit(x); carry = ((d & IBASE) != 0); @@ -135,25 +142,28 @@ word big_plus(word x, word y, int signbit) x = rest(x); z = &rest(*z); } + if (carry) { *z = make(INT, 1, 0); } - return (r); + + return r; } word bigsub(word x, word y) { - if (poz(x)) { - if (poz(y)) { + if (big_is_positive(x)) { + if (big_is_positive(y)) { return (big_sub(x, y)); } else { return (big_plus(x, y, 0)); /* poz x, negative y */ } - } else if (poz(y)) { + + } else if (big_is_positive(y)) { return (big_plus(x, y, SIGNBIT)); /* negative x, poz y */ - } else { - return (big_sub(y, x)); /* both negative */ } + + return (big_sub(y, x)); /* both negative */ } /* ignore input signs, treat x,y as positive */ @@ -166,6 +176,7 @@ word big_sub(word x, word y) word *p = NULL; /* pointer to trailing zeros, if any */ x = rest(x); y = rest(y); + while (x && y) { /* this loop has been unwrapped once, see above */ d = digit(x) - digit(y) - borrow; borrow = (d & IBASE) != 0; @@ -179,6 +190,7 @@ word big_sub(word x, word y) y = rest(y); z = &rest(*z); } + while (y) { /* at most one of these two loops will be invoked */ d = -digit(y) - borrow; borrow = ((d & IBASE) != 0); @@ -191,18 +203,21 @@ word big_sub(word x, word y) y = rest(y); z = &rest(*z); } + while (x) { /* alternative loop */ d = digit(x) - borrow; borrow = ((d & IBASE) != 0); d = d & MAXDIGIT; *z = make(INT, d, 0); - if (d) + if (d) { p = NULL; - else if (!p) + } else if (!p) { p = z; + } x = rest(x); z = &rest(*z); } + if (borrow) { /* result is negative - take complement and add 1 */ p = NULL; d = (digit(r) ^ MAXDIGIT) + 1; @@ -213,29 +228,36 @@ word big_sub(word x, word y) d = (digit(*z) ^ MAXDIGIT) + borrow; borrow = ((d & IBASE) != 0); digit(*z) = d = d & MAXDIGIT; - if (d) + if (d) { p = NULL; - else if (!p) + } else if (!p) { p = z; + } z = &rest(*z); } } - if (p) + + if (p) { *p = 0; /* remove redundant (ie trailing) zeros */ - return (r); + } + + return r; } /* returns +ve,0,-ve as x greater than, equal, less than y */ int bigcmp(word x, word y) { - word d, r, s = neg(x); - if (neg(y) != s) { + word s = big_is_negative(x); + + if (big_is_negative(y) != s) { return (s ? -1 : 1); } - r = digit0(x) - digit0(y); + + word r = digit0(x) - digit0(y); for (;;) { x = rest(x); y = rest(y); + if (!x) { if (y) { return (s ? 1 : -1); @@ -243,10 +265,12 @@ int bigcmp(word x, word y) return (s ? -r : r); } } + if (!y) { return (s ? -1 : 1); } - d = digit(x) - digit(y); + + word d = digit(x) - digit(y); if (d) { r = d; } @@ -256,27 +280,34 @@ int bigcmp(word x, word y) /* naive multiply - quadratic */ word bigtimes(word x, word y) { + word r = make(INT, 0, 0); + if (len(x) < len(y)) { word hold = x; x = y; y = hold; } /* important optimisation */ - word r = make(INT, 0, 0); - word d = digit0(y); - word s = neg(y); - word n = 0; + if (bigzero(x)) { - return (r); /* short cut */ + return r; /* short cut */ } + + word d = digit0(y); + word s = big_is_negative(y); + word n = 0; + for (;;) { if (d) { r = bigplus(r, shift(n, stimes(x, d))); } + n++; y = rest(y); + if (!y) { - return (s != neg(x) ? bignegate(r) : r); + return (s != big_is_negative(x) ? bignegate(r) : r); } + d = digit(y); } } @@ -288,7 +319,7 @@ word shift(word n, word x) while (n--) { x = make(INT, 0, x); } - return (x); + return x; } /* multiply big x (>=0) by digit n (>0) */ @@ -298,37 +329,39 @@ word stimes(word x, word n) word carry = d >> DIGITWIDTH; word r = make(INT, d & MAXDIGIT, 0); word *y = &rest(r); + while ((x = rest(x))) { - d = n * digit(x) + carry, - *y = make(INT, d & MAXDIGIT, 0), y = &rest(*y), carry = d >> DIGITWIDTH; + d = n * digit(x) + carry; + *y = make(INT, d & MAXDIGIT, 0); + y = &rest(*y); + carry = d >> DIGITWIDTH; } + if (carry) { *y = make(INT, carry, 0); } - return (r); + + return r; } /* may assume y~=0 */ word bigdiv(word x, word y) { - word s1, s2, q; - /* make x,y positive and remember signs */ - if ((s1 = neg(y))) { + word s1 = big_is_negative(y); + if (s1) { y = make(INT, digit0(y), rest(y)); } - if (neg(x)) { - x = make(INT, digit0(x), rest(x)), s2 = !s1; - } else { - s2 = s1; + + word s2 = s1; + if (big_is_negative(x)) { + x = make(INT, digit0(x), rest(x)); + s2 = !s1; } /* effect: s1 set iff y negative, s2 set iff signs mixed */ - if (rest(y)) { - q = longdiv(x, y); - } else { - q = shortdiv(x, digit(y)); - } + + word q = rest(y) ? longdiv(x, y) : shortdiv(x, digit(y)); if (s2) { if (!bigzero(b_rem)) { @@ -343,30 +376,33 @@ word bigdiv(word x, word y) } } } + if (!bigzero(q)) { digit(q) = SIGNBIT | digit(q); } } - return (q); + + return q; } /* may assume y~=0 */ word bigmod(word x, word y) { - word s1, s2; + word s1 = big_is_negative(y); /* make x,y positive and remember signs */ - if ((s1 = neg(y))) { + if (s1) { y = make(INT, digit0(y), rest(y)); } - if (neg(x)) { - x = make(INT, digit0(x), rest(x)), s2 = !s1; - } else { - s2 = s1; + word s2 = s1; + if (big_is_negative(x)) { + x = make(INT, digit0(x), rest(x)); + s2 = !s1; } /* effect: s1 set iff y negative, s2 set iff signs mixed */ + if (rest(y)) { longdiv(x, y); } else { @@ -378,6 +414,7 @@ word bigmod(word x, word y) b_rem = bigsub(y, b_rem); } } + return (s1 ? bignegate(b_rem) : b_rem); } @@ -396,14 +433,15 @@ word bigmod(word x, word y) /* may assume - x>=0,n>0 */ word shortdiv(word x, word n) { - word d = digit(x), s_rem, q = 0; + word d = digit(x); + word q = 0; + while ((x = rest(x))) { /* reverse rest(x) into q */ - q = make(INT, d, q), d = digit(x); /* leaving most sig. digit in d */ + q = make(INT, d, q); + d = digit(x); /* leaving most sig. digit in d */ } - word tmp; x = q; - s_rem = d % n; d = d / n; if (d || !q) { @@ -412,14 +450,20 @@ word shortdiv(word x, word n) q = 0; } + word s_rem = d % n; while (x) { /* in situ division of q by n AND destructive reversal */ - d = s_rem * IBASE + digit(x), digit(x) = d / n, s_rem = d % n, - tmp = x, x = rest(x), rest(tmp) = q, q = tmp; + d = s_rem * IBASE + digit(x); + digit(x) = d / n; + s_rem = d % n; + word tmp = x; + x = rest(x); + rest(tmp) = q; + q = tmp; } b_rem = make(INT, s_rem, 0); - return (q); + return q; } /* divide big x by big y returning quotient, leaving @@ -427,56 +471,66 @@ word shortdiv(word x, word n) /* may assume - x>=0,y>0 */ word longdiv(word x, word y) { - word n, q, ly, y1, scale; if (bigcmp(x, y) < 0) { b_rem = x; return (make(INT, 0, 0)); } - y1 = msd(y); - if ((scale = IBASE / (y1 + 1)) > 1) { /* rescale if necessary */ - x = stimes(x, scale), y = stimes(y, scale), y1 = msd(y); + + word y1 = msd(y); + word scale = IBASE / (y1 + 1); + if (scale > 1) { /* rescale if necessary */ + x = stimes(x, scale); + y = stimes(y, scale); + y1 = msd(y); } - n = q = 0; - ly = len(y); + word n = 0; + word ly = len(y); while (bigcmp(x, y = make(INT, 0, y)) >= 0) { n++; } y = rest(y); /* want largest y not exceeding x */ ly += n; + word q = 0; for (;;) { - word d, lx = len(x); - if (lx < ly) { - d = 0; - } else if (lx == ly) { + word d = 0; + word lx = len(x); + + if (lx == ly) { if (bigcmp(x, y) >= 0) { - x = bigsub(x, y), d = 1; - } else { - d = 0; + x = bigsub(x, y); + d = 1; } - } else { + + } else if (lx > ly) { d = ms2d(x) / y1; if (d > MAXDIGIT) { d = MAXDIGIT; } + if ((d -= 2) > 0) { x = bigsub(x, stimes(y, d)); } else { d = 0; } + if (bigcmp(x, y) >= 0) { - x = bigsub(x, y), d++; + x = bigsub(x, y); + d++; if (bigcmp(x, y) >= 0) { - x = bigsub(x, y), d++; + x = bigsub(x, y); + d++; } } } + q = make(INT, d, q); if (n-- == 0) { - b_rem = scale == 1 ? x : shortdiv(x, scale); - return (q); + b_rem = (scale == 1) ? x : shortdiv(x, scale); + return q; } + ly--; y = rest(y); } @@ -489,7 +543,7 @@ word len(word x) while ((x = rest(x))) { n++; } - return (n); + return n; } /* most significant digit of big x */ @@ -498,7 +552,7 @@ word msd(word x) while (rest(x)) { x = rest(x); } - return (digit(x)); /* sign? */ + return digit(x); /* sign? */ } /* most significant 2 digits of big x (len>=2) */ @@ -507,7 +561,8 @@ word ms2d(word x) word d = digit(x); x = rest(x); while (rest(x)) { - d = digit(x), x = rest(x); + d = digit(x); + x = rest(x); } return (digit(x) * IBASE + d); } @@ -515,10 +570,10 @@ word ms2d(word x) /* assumes y poz */ word bigpow(word x, word y) { - word d, r = make(INT, 1, 0); - while (rest(y)) { /* this loop has been unwrapped once, see below */ + word r = make(INT, 1, 0); + while (rest(y)) { word i = DIGITWIDTH; - d = digit(y); + word d = digit(y); while (i--) { if (d & 1) { r = bigtimes(r, x); @@ -528,31 +583,35 @@ word bigpow(word x, word y) } y = rest(y); } - d = digit(y); + + word d = digit(y); if (d & 1) { r = bigtimes(r, x); } + while (d >>= 1) { x = bigtimes(x, x); if (d & 1) { r = bigtimes(r, x); } } - return (r); + + return r; } double bigtodbl(word x) { - word s = neg(x); - double b = 1.0, r = (double)digit0(x); + double b = 1.0; + double r = (double)digit0(x); + x = rest(x); while (x) { - b = b * IBASE, r = r + b * digit(x), x = rest(x); - } - if (s) { - return (-r); + b = b * IBASE; + r = r + b * digit(x); + x = rest(x); } - return (r); + + return big_is_negative(x) ? -r : r; } /* small end first */ /* note: can return oo, -oo @@ -561,40 +620,40 @@ double bigtodbl(word x) /* not currently used */ long double bigtoldbl(word x) { - int s=neg(x); - long double b=1.0L, r=digit0(x); + long double b = 1.0L; + long double r = (long double)digit0(x); + x = rest(x); while (x) { - b=b*IBASE,r=r+b*digit(x),x=rest(x); - } - if (s) { - return(-r); + b = b * IBASE; + r = r + b * digit(x); + x = rest(x); } - return(r); + + return big_is_negative(x) ? -r : r; } /* not compatible with std=c90, lib fns eg sqrtl broken */ /* entier */ word dbltobig(double x) { - word s = (x < 0); word r = make(INT, 0, 0); word *p = &r; - double y = floor(x); + double y = fabs(floor(x)); - for (y = fabs(y);;) { + while (y > 0.0) { double n = fmod(y, (double)IBASE); digit(*p) = (word) n; y = (y - n) / (double)IBASE; if (y > 0.0) { rest(*p) = make(INT, 0, 0), p = &rest(*p); - } else { - break; } } - if (s) { + + if (x < 0) { digit(r) = SIGNBIT | digit(r); } - return (r); + + return r; } /* produces junk in low order digits if x exceeds range in which integer @@ -612,28 +671,35 @@ word dbltobig(double x) /* logarithm of big x */ double biglog(word x) { + if (big_is_negative(x) || bigzero(x)) { + errno = EDOM; + math_error("log"); + } + word n = 0; double r = digit(x); - if (neg(x) || bigzero(x)) { - errno = EDOM, math_error("log"); - } while ((x = rest(x))) { - n++, r = digit(x) + r / IBASE; + n++; + r = digit(x) + r / IBASE; } + return (log(r) + n * logIBASE); } /* logarithm of big x */ double biglog10(word x) { + if (big_is_negative(x) || bigzero(x)) { + errno = EDOM; + math_error("log10"); + } + word n = 0; double r = digit(x); - if (neg(x) || bigzero(x)) { - errno = EDOM, math_error("log10"); - } while ((x = rest(x))) { n++, r = digit(x) + r / IBASE; } + return (log10(r) + n * log10IBASE); } @@ -642,16 +708,22 @@ double biglog10(word x) /* read a big number (in decimal) */ word bigscan(char *p) { - word s = 0, r = make(INT, 0, 0); + word s = 0; + word r = make(INT, 0, 0); if (*p == '-') { - s = 1, p++; /* optional leading `-' (for NUMVAL) */ + s = 1; + p++; /* optional leading `-' (for NUMVAL) */ } while (*p) { - word d = *p - '0', f = 10; + word d = *p - '0'; + word f = 10; p++; + while (*p && f < PTEN) { - d = 10 * d + *p - '0', f = 10 * f, p++; + d = 10 * d + *p - '0'; + f = 10 * f; + p++; } /* rest of loop does r=f*r+d; (in situ) */ @@ -659,18 +731,24 @@ word bigscan(char *p) word carry = d >> DIGITWIDTH; word *x = &rest(r); digit(r) = d & MAXDIGIT; + while (*x) { - d = f * digit(*x) + carry, - digit(*x) = d & MAXDIGIT, carry = d >> DIGITWIDTH, x = &rest(*x); + d = f * digit(*x) + carry; + digit(*x) = d & MAXDIGIT; + carry = d >> DIGITWIDTH; + x = &rest(*x); } + if (carry) { *x = make(INT, carry, 0); } } + if (s && !bigzero(r)) { digit(r) = digit(r) | SIGNBIT; } - return (r); + + return r; } /* code to handle (unsigned) exponent commented out */ @@ -679,21 +757,26 @@ word bigscan(char *p) /* read unsigned hex number in '\0'-terminated string p to q */ word bigxscan(char *p, char *q) { - word r; /* will hold result */ - word *x = &r; if (*p == '0' && !p[1]) { return make(INT, 0, 0); } + + word r; /* will hold result */ + word *x = &r; + while (q > p) { unsigned long long hold; - q = q - p < 15 ? p : q - 15; /* read upto 15 hex digits from small end */ + q = (q - p < 15) ? p : (q - 15); /* read upto 15 hex digits from small end */ sscanf(q, "%llx", &hold); *q = '\0'; word count = 4; /* 15 hex digits => 4 bignum digits */ while (count-- && !(hold == 0 && q == p)) { - *x = make(INT, hold & MAXDIGIT, 0), hold >>= DIGITWIDTH, x = &rest(*x); + *x = make(INT, hold & MAXDIGIT, 0); + hold >>= DIGITWIDTH; + x = &rest(*x); } } + return r; } @@ -703,6 +786,7 @@ word bigoscan(char *p, char *q) { word r; /* will hold result */ word *x = &r; + while (q > p) { unsigned hold; q = q - p < 5 ? p : q - 5; /* read (upto) 5 octal digits from small end */ @@ -710,6 +794,7 @@ word bigoscan(char *p, char *q) *q = '\0'; *x = make(INT, hold, 0), x = &rest(*x); } + return r; } @@ -723,8 +808,10 @@ word digitval(char c) done and that z fully evaluated */ word strtobig(word z, int base) { - word s = 0, r = make(INT, 0, 0), PBASE = PTEN; + word s = 0; + word r = make(INT, 0, 0); + word PBASE = PTEN; if (base == 16) { PBASE = PSIXTEEN; } else if (base == 8) { @@ -732,7 +819,8 @@ word strtobig(word z, int base) } if (z != NIL && hd[z] == '-') { - s = 1, z = tl[z]; /* optional leading `-' (for NUMVAL) */ + s = 1; + z = tl[z]; /* optional leading `-' (for NUMVAL) */ } if (base != 10) { @@ -742,8 +830,11 @@ word strtobig(word z, int base) while (z != NIL) { word d = digitval(hd[z]), f = base; z = tl[z]; + while (z != NIL && f < PBASE) { - d = base * d + digitval(hd[z]), f = base * f, z = tl[z]; + d = base * d + digitval(hd[z]); + f = base * f; + z = tl[z]; } /* rest of loop does r=f*r+d; (in situ) */ @@ -751,10 +842,12 @@ word strtobig(word z, int base) word carry = d >> DIGITWIDTH; word *x = &rest(r); digit(r) = d & MAXDIGIT; + while (*x) { d = f * digit(*x) + carry, digit(*x) = d & MAXDIGIT, carry = d >> DIGITWIDTH, x = &rest(*x); } + if (carry) { *x = make(INT, carry, 0); } @@ -764,19 +857,19 @@ word strtobig(word z, int base) digit(r) = digit(r) | SIGNBIT; } - return (r); + return r; } word bigtostr(word x) /* number to decimal string (as Miranda list) */ { - word x1, sign, s = NIL; + word sign = big_is_negative(x); + word s = NIL; #ifdef DEBUG extern int debug; if (debug & 04) { /* print octally */ word d = digit0(x); - sign = neg(x); for (;;) { word i = OCTW; while (i-- || d) { @@ -798,15 +891,15 @@ word bigtostr(word x) /* number to decimal string (as Miranda list) */ return (str_conv(dicp)); } - sign = neg(x); - x1 = make(INT, digit0(x), 0); /* reverse x into x1 */ + word x1 = make(INT, digit0(x), 0); /* reverse x into x1 */ while ((x = rest(x))) { x1 = make(INT, digit(x), x1); } x = x1; for (;;) { /* in situ division of (reversed order) x by PTEN */ - word d = digit(x), rem = d % PTEN; + word d = digit(x); + word rem = d % PTEN; d = d / PTEN; x1 = rest(x); @@ -817,8 +910,10 @@ word bigtostr(word x) /* number to decimal string (as Miranda list) */ } while (x1) { - d = rem * IBASE + digit(x1), - digit(x1) = d / PTEN, rem = d % PTEN, x1 = rest(x1); + d = rem * IBASE + digit(x1); + digit(x1) = d / PTEN; + rem = d % PTEN; + x1 = rest(x1); } /* end of in situ division (also uses x1 as temporary) */ @@ -839,7 +934,8 @@ word bigtostr(word x) /* number to decimal string (as Miranda list) */ /* integer to hexadecimal string (as Miranda list) */ word bigtostrx(word x) { - word r = NIL, s = neg(x); + word r = NIL; + word sign = big_is_negative(x); while (x) { word count = 4; /* 60 bits => 20 octal digits => 4 bignum digits */ unsigned long long factor = 1; @@ -854,22 +950,25 @@ word bigtostrx(word x) r = cons(*q, r); } } + while (digit(r) == '0' && rest(r) != NIL) { r = rest(r); /* remove redundant leading 0's */ } r = cons('0', cons('x', r)); - if (s) { + if (sign) { r = cons('-', r); } - return (r); + return r; } /* integer to octal string (as Miranda list) */ word bigtostr8(word x) { - word r = NIL, s = neg(x); + word r = NIL; + word sign = big_is_negative(x); + while (x) { char *q = dicp + 5; sprintf(dicp, "%.5lo", digit0(x)); @@ -878,14 +977,18 @@ word bigtostr8(word x) } x = rest(x); } + while (digit(r) == '0' && rest(r) != NIL) { r = rest(r); /* remove redundant leading 0's */ } + r = cons('0', cons('o', r)); - if (s) { + + if (sign) { r = cons('-', r); } - return (r); + + return r; } #ifdef DEBUG @@ -896,9 +999,11 @@ wff(word x) if (tag[x] != INT) { printf("BAD TAG %d\n", tag[x]); } - if (neg(x) && !digit0(x) && !rest(x)) { + + if (big_is_negative(x) && !digit0(x) && !rest(x)) { printf("NEGATIVE ZERO!\n"); } + if (digit0(x) & (~MAXDIGIT)) { printf("OVERSIZED DIGIT!\n"); } @@ -912,6 +1017,7 @@ wff(word x) printf("TRAILING ZERO!\n"); } } + return (y); } @@ -921,7 +1027,8 @@ normalise(word x) if (rest(x)) { rest(x) = norm1(rest(x)); } - return (wff(x)); + + return wff(x); } norm1(word x) @@ -929,6 +1036,7 @@ norm1(word x) if (rest(x)) { rest(x) = norm1(rest(x)); } + return (!digit(x) && !rest(x) ? 0 : x); } -- cgit v1.2.1