support for rational numbers
make floor and friends return an integer (make it closer to SICStus).
This commit is contained in:
parent
09fef1a033
commit
293dadb003
179
C/arith1.c
179
C/arith1.c
@ -37,9 +37,7 @@ float_to_int(Float v)
|
|||||||
if (i-v == 0.0) {
|
if (i-v == 0.0) {
|
||||||
return MkIntegerTerm(i);
|
return MkIntegerTerm(i);
|
||||||
} else {
|
} else {
|
||||||
MP_INT o;
|
return Yap_gmp_float_to_big(v);
|
||||||
mpz_init_set_d(&o, v);
|
|
||||||
return Yap_MkBigIntTerm(&o);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return MkIntegerTerm(v);
|
return MkIntegerTerm(v);
|
||||||
@ -48,24 +46,6 @@ float_to_int(Float v)
|
|||||||
|
|
||||||
#define RBIG_FL(v) return(float_to_int(v))
|
#define RBIG_FL(v) return(float_to_int(v))
|
||||||
|
|
||||||
#if USE_GMP
|
|
||||||
static Term
|
|
||||||
process_iso_error(MP_INT *big, Term t, char *operation)
|
|
||||||
{ /* iso */
|
|
||||||
Int sz = 2+mpz_sizeinbase(big,10);
|
|
||||||
char *s = Yap_AllocCodeSpace(sz);
|
|
||||||
|
|
||||||
if (s != NULL) {
|
|
||||||
mpz_get_str(s, 10, big);
|
|
||||||
Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is %s(%s)", operation, s);
|
|
||||||
Yap_FreeCodeSpace(s);
|
|
||||||
RERROR();
|
|
||||||
} else {
|
|
||||||
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is %s(t)",operation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct init_un_eval {
|
typedef struct init_un_eval {
|
||||||
char *OpName;
|
char *OpName;
|
||||||
arith1_op f;
|
arith1_op f;
|
||||||
@ -104,7 +84,7 @@ get_float(Term t) {
|
|||||||
}
|
}
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
if (IsBigIntTerm(t)) {
|
if (IsBigIntTerm(t)) {
|
||||||
return mpz_get_d(Yap_BigIntOfTerm(t));
|
return Yap_gmp_to_float(t);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0.0;
|
return 0.0;
|
||||||
@ -434,33 +414,13 @@ eval1(Int fi, Term t) {
|
|||||||
|
|
||||||
switch (ETypeOfTerm(t)) {
|
switch (ETypeOfTerm(t)) {
|
||||||
case long_int_e:
|
case long_int_e:
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return t;
|
||||||
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is floor(%f)", IntegerOfTerm(t));
|
|
||||||
} else {
|
|
||||||
RFLOAT(IntegerOfTerm(t));
|
|
||||||
}
|
|
||||||
case double_e:
|
case double_e:
|
||||||
dbl = FloatOfTerm(t);
|
dbl = FloatOfTerm(t);
|
||||||
break;
|
break;
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return Yap_gmp_floor(t);
|
||||||
MP_INT *big = Yap_BigIntOfTerm(t);
|
|
||||||
Int sz = 2+mpz_sizeinbase(big,10);
|
|
||||||
char *s = Yap_AllocCodeSpace(sz);
|
|
||||||
|
|
||||||
if (s != NULL) {
|
|
||||||
mpz_get_str(s, 10, big);
|
|
||||||
Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is floor(%s)", s);
|
|
||||||
Yap_FreeCodeSpace(s);
|
|
||||||
RERROR();
|
|
||||||
} else {
|
|
||||||
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is floor(t)");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dbl = mpz_get_d(Yap_BigIntOfTerm(t));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -483,22 +443,13 @@ eval1(Int fi, Term t) {
|
|||||||
Float dbl;
|
Float dbl;
|
||||||
switch (ETypeOfTerm(t)) {
|
switch (ETypeOfTerm(t)) {
|
||||||
case long_int_e:
|
case long_int_e:
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return t;
|
||||||
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is ceiling(%f)", IntegerOfTerm(t));
|
|
||||||
} else {
|
|
||||||
RFLOAT(IntegerOfTerm(t));
|
|
||||||
}
|
|
||||||
case double_e:
|
case double_e:
|
||||||
dbl = FloatOfTerm(t);
|
dbl = FloatOfTerm(t);
|
||||||
break;
|
break;
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return Yap_gmp_ceiling(t);
|
||||||
return process_iso_error(Yap_BigIntOfTerm(t), t, "ceiling");
|
|
||||||
} else {
|
|
||||||
dbl = mpz_get_d(Yap_BigIntOfTerm(t));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -522,21 +473,13 @@ eval1(Int fi, Term t) {
|
|||||||
|
|
||||||
switch (ETypeOfTerm(t)) {
|
switch (ETypeOfTerm(t)) {
|
||||||
case long_int_e:
|
case long_int_e:
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return t;
|
||||||
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is round(%ld)", IntegerOfTerm(t));
|
|
||||||
} else {
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
case double_e:
|
case double_e:
|
||||||
dbl = FloatOfTerm(t);
|
dbl = FloatOfTerm(t);
|
||||||
break;
|
break;
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) {
|
return Yap_gmp_round(t);
|
||||||
return process_iso_error(Yap_BigIntOfTerm(t), t, "round");
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -560,19 +503,13 @@ eval1(Int fi, Term t) {
|
|||||||
Float dbl;
|
Float dbl;
|
||||||
switch (ETypeOfTerm(t)) {
|
switch (ETypeOfTerm(t)) {
|
||||||
case long_int_e:
|
case long_int_e:
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
|
||||||
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is round(%ld)", IntegerOfTerm(t));
|
|
||||||
}
|
|
||||||
return t;
|
return t;
|
||||||
case double_e:
|
case double_e:
|
||||||
dbl = FloatOfTerm(t);
|
dbl = FloatOfTerm(t);
|
||||||
break;
|
break;
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return Yap_gmp_trunc(t);
|
||||||
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is round(BIGNUM)");
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -588,18 +525,10 @@ eval1(Int fi, Term t) {
|
|||||||
(%f)",dbl);
|
(%f)",dbl);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (dbl <= (Float)Int_MAX && dbl >= (Float)Int_MIN) {
|
if (dbl < 0.0)
|
||||||
RINT((Int) dbl);
|
RBIG_FL(ceil(dbl));
|
||||||
} else {
|
else
|
||||||
#ifdef USE_GMP
|
RBIG_FL(floor(dbl));
|
||||||
MP_INT new;
|
|
||||||
|
|
||||||
mpz_init_set_d(&new, dbl);
|
|
||||||
RBIG(&new);
|
|
||||||
#else
|
|
||||||
return Yap_ArithError(EVALUATION_ERROR_INT_OVERFLOW, MkFloatTerm(dbl), "integer/1");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case op_float:
|
case op_float:
|
||||||
switch (ETypeOfTerm(t)) {
|
switch (ETypeOfTerm(t)) {
|
||||||
@ -609,11 +538,37 @@ eval1(Int fi, Term t) {
|
|||||||
return t;
|
return t;
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
RFLOAT(mpz_get_d(Yap_BigIntOfTerm(t)));
|
RFLOAT(Yap_gmp_to_float(t));
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
}
|
}
|
||||||
|
case op_rational:
|
||||||
|
switch (ETypeOfTerm(t)) {
|
||||||
|
case long_int_e:
|
||||||
|
return t;
|
||||||
|
#ifdef USE_GMP
|
||||||
|
case double_e:
|
||||||
|
return Yap_gmp_float_to_rational(FloatOfTerm(t));
|
||||||
|
#endif
|
||||||
|
case big_int_e:
|
||||||
|
return t;
|
||||||
|
default:
|
||||||
|
RERROR();
|
||||||
|
}
|
||||||
|
case op_rationalize:
|
||||||
|
switch (ETypeOfTerm(t)) {
|
||||||
|
case long_int_e:
|
||||||
|
return t;
|
||||||
|
#ifdef USE_GMP
|
||||||
|
case double_e:
|
||||||
|
return Yap_gmp_float_rationalize(FloatOfTerm(t));
|
||||||
|
#endif
|
||||||
|
case big_int_e:
|
||||||
|
return t;
|
||||||
|
default:
|
||||||
|
RERROR();
|
||||||
|
}
|
||||||
case op_abs:
|
case op_abs:
|
||||||
switch (ETypeOfTerm(t)) {
|
switch (ETypeOfTerm(t)) {
|
||||||
case long_int_e:
|
case long_int_e:
|
||||||
@ -622,13 +577,7 @@ eval1(Int fi, Term t) {
|
|||||||
RFLOAT(fabs(FloatOfTerm(t)));
|
RFLOAT(fabs(FloatOfTerm(t)));
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
{
|
return Yap_gmp_abs_big(t);
|
||||||
MP_INT new;
|
|
||||||
|
|
||||||
mpz_init_set(&new, Yap_BigIntOfTerm(t));
|
|
||||||
mpz_abs(&new, &new);
|
|
||||||
RBIG(&new);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -641,13 +590,7 @@ eval1(Int fi, Term t) {
|
|||||||
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "msb(%f)", FloatOfTerm(t));
|
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "msb(%f)", FloatOfTerm(t));
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
{ MP_INT *big = Yap_BigIntOfTerm(t);
|
return Yap_gmp_msb(t);
|
||||||
if ( mpz_sgn(big) <= 0 ) {
|
|
||||||
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t,
|
|
||||||
"msb/1 received bignum");
|
|
||||||
}
|
|
||||||
RINT(mpz_sizeinbase(big,2));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -660,13 +603,7 @@ eval1(Int fi, Term t) {
|
|||||||
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "lsb(%f)", FloatOfTerm(t));
|
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "lsb(%f)", FloatOfTerm(t));
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
{ MP_INT *big = Yap_BigIntOfTerm(t);
|
return Yap_gmp_lsb(t);
|
||||||
if ( mpz_sgn(big) <= 0 ) {
|
|
||||||
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t,
|
|
||||||
"lsb/1 received bignum");
|
|
||||||
}
|
|
||||||
RINT(mpz_scan1(big,0));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -679,13 +616,7 @@ eval1(Int fi, Term t) {
|
|||||||
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "popcount(%f)", FloatOfTerm(t));
|
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "popcount(%f)", FloatOfTerm(t));
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
{ MP_INT *big = Yap_BigIntOfTerm(t);
|
return Yap_gmp_popcount(t);
|
||||||
if ( mpz_sgn(big) <= 0 ) {
|
|
||||||
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t,
|
|
||||||
"popcount/1 received negative bignum");
|
|
||||||
}
|
|
||||||
RINT(mpz_popcount(big));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -707,11 +638,7 @@ eval1(Int fi, Term t) {
|
|||||||
break;
|
break;
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return Yap_gmp_float_fractional_part(t);
|
||||||
return process_iso_error(Yap_BigIntOfTerm(t), t, "float_fractional_part");
|
|
||||||
} else {
|
|
||||||
RFLOAT(0.0);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -719,21 +646,13 @@ eval1(Int fi, Term t) {
|
|||||||
case op_fintp:
|
case op_fintp:
|
||||||
switch (ETypeOfTerm(t)) {
|
switch (ETypeOfTerm(t)) {
|
||||||
case long_int_e:
|
case long_int_e:
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is float_integer_part(%f)", IntegerOfTerm(t));
|
||||||
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is float_integer_part(%f)", IntegerOfTerm(t));
|
|
||||||
} else {
|
|
||||||
RFLOAT(IntegerOfTerm(t));
|
|
||||||
}
|
|
||||||
case double_e:
|
case double_e:
|
||||||
RFLOAT(rint(FloatOfTerm(t)));
|
RFLOAT(rint(FloatOfTerm(t)));
|
||||||
break;
|
break;
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
return Yap_gmp_float_integer_part(t);
|
||||||
return process_iso_error(Yap_BigIntOfTerm(t), t, "float_integer_part");
|
|
||||||
} else {
|
|
||||||
RFLOAT(mpz_get_d(Yap_BigIntOfTerm(t)));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -755,7 +674,7 @@ eval1(Int fi, Term t) {
|
|||||||
}
|
}
|
||||||
case big_int_e:
|
case big_int_e:
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
RINT(mpz_sgn(Yap_BigIntOfTerm(t)));
|
return Yap_gmp_sign(t);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
RERROR();
|
RERROR();
|
||||||
@ -818,6 +737,8 @@ static InitUnEntry InitUnTab[] = {
|
|||||||
{"lgamma", op_lgamma},
|
{"lgamma", op_lgamma},
|
||||||
{"erf",op_erf},
|
{"erf",op_erf},
|
||||||
{"erfc",op_erfc},
|
{"erfc",op_erfc},
|
||||||
|
{"rational",op_rational},
|
||||||
|
{"rationalize",op_rationalize},
|
||||||
{"random", op_random1}
|
{"random", op_random1}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
84
C/bignum.c
84
C/bignum.c
@ -83,7 +83,7 @@ Yap_MkBigRatTerm(MP_RAT *big)
|
|||||||
}
|
}
|
||||||
H[0] = (CELL)FunctorBigInt;
|
H[0] = (CELL)FunctorBigInt;
|
||||||
H[1] = BIG_RATIONAL;
|
H[1] = BIG_RATIONAL;
|
||||||
dst->_mp_alloc = 0;
|
dst->_mp_size = 0;
|
||||||
rat = (MP_RAT *)(dst+1);
|
rat = (MP_RAT *)(dst+1);
|
||||||
rat->_mp_num._mp_size = num->_mp_size;
|
rat->_mp_num._mp_size = num->_mp_size;
|
||||||
rat->_mp_num._mp_alloc = num->_mp_alloc;
|
rat->_mp_num._mp_alloc = num->_mp_alloc;
|
||||||
@ -95,7 +95,7 @@ Yap_MkBigRatTerm(MP_RAT *big)
|
|||||||
nlimbs = (den->_mp_alloc)*(sizeof(mp_limb_t)/CellSize);
|
nlimbs = (den->_mp_alloc)*(sizeof(mp_limb_t)/CellSize);
|
||||||
memmove((void *)(H), (const void *)(den->_mp_d), nlimbs*CellSize);
|
memmove((void *)(H), (const void *)(den->_mp_d), nlimbs*CellSize);
|
||||||
H += nlimbs;
|
H += nlimbs;
|
||||||
dst->_mp_size = (H-(CELL *)rat);
|
dst->_mp_alloc = (H-(CELL *)(dst+1));
|
||||||
H[0] = EndSpecials;
|
H[0] = EndSpecials;
|
||||||
H++;
|
H++;
|
||||||
return AbsAppl(ret);
|
return AbsAppl(ret);
|
||||||
@ -113,6 +113,17 @@ Yap_BigRatOfTerm(Term t)
|
|||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_RatTermToApplTerm(Term t)
|
||||||
|
{
|
||||||
|
Term ts[2];
|
||||||
|
MP_RAT *rat = Yap_BigRatOfTerm(t);
|
||||||
|
|
||||||
|
ts[0] = Yap_MkBigIntTerm(mpq_numref(rat));
|
||||||
|
ts[1] = Yap_MkBigIntTerm(mpq_denref(rat));
|
||||||
|
return Yap_MkApplTerm(FunctorRDiv,2,ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -150,7 +161,11 @@ p_is_bignum(void)
|
|||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
Term t = Deref(ARG1);
|
Term t = Deref(ARG1);
|
||||||
return(
|
return(
|
||||||
IsNonVarTerm(t) && IsApplTerm(t) && FunctorOfTerm(t) == FunctorBigInt);
|
IsNonVarTerm(t) &&
|
||||||
|
IsApplTerm(t) &&
|
||||||
|
FunctorOfTerm(t) == FunctorBigInt &&
|
||||||
|
RepAppl(t)[1] == BIG_INT
|
||||||
|
);
|
||||||
#else
|
#else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
@ -166,9 +181,72 @@ p_has_bignums(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Int
|
||||||
|
p_is_rational(void)
|
||||||
|
{
|
||||||
|
Term t = Deref(ARG1);
|
||||||
|
if (IsVarTerm(t))
|
||||||
|
return FALSE;
|
||||||
|
if (IsIntTerm(t))
|
||||||
|
return TRUE;
|
||||||
|
if (IsApplTerm(t)) {
|
||||||
|
Functor f = FunctorOfTerm(t);
|
||||||
|
CELL *pt;
|
||||||
|
|
||||||
|
if (f == FunctorLongInt)
|
||||||
|
return TRUE;
|
||||||
|
if (f != FunctorBigInt)
|
||||||
|
return FALSE;
|
||||||
|
pt = RepAppl(t);
|
||||||
|
return ( pt[1] == BIG_RATIONAL || pt[1] == BIG_INT );
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Int
|
||||||
|
p_rational(void)
|
||||||
|
{
|
||||||
|
#ifdef USE_GMP
|
||||||
|
Term t = Deref(ARG1);
|
||||||
|
Functor f;
|
||||||
|
CELL *pt;
|
||||||
|
MP_RAT *rat;
|
||||||
|
Term t1, t2;
|
||||||
|
|
||||||
|
if (IsVarTerm(t))
|
||||||
|
return FALSE;
|
||||||
|
if (!IsApplTerm(t))
|
||||||
|
return FALSE;
|
||||||
|
f = FunctorOfTerm(t);
|
||||||
|
if (f != FunctorBigInt)
|
||||||
|
return FALSE;
|
||||||
|
pt = RepAppl(t);
|
||||||
|
if (pt[1] != BIG_RATIONAL)
|
||||||
|
return FALSE;
|
||||||
|
rat = Yap_BigRatOfTerm(t);
|
||||||
|
while ((t1 = Yap_MkBigIntTerm(mpq_numref(rat))) == TermNil ||
|
||||||
|
(t2 = Yap_MkBigIntTerm(mpq_denref(rat))) == TermNil) {
|
||||||
|
UInt size =
|
||||||
|
(mpq_numref(rat)->_mp_alloc)*(sizeof(mp_limb_t)/CellSize) +
|
||||||
|
(mpq_denref(rat)->_mp_alloc)*(sizeof(mp_limb_t)/CellSize);
|
||||||
|
if (!Yap_gcl(size, 3, ENV, P)) {
|
||||||
|
Yap_Error(OUT_OF_STACK_ERROR, t, Yap_ErrorMessage);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
Yap_unify(ARG2, t1) &&
|
||||||
|
Yap_unify(ARG3, t2);
|
||||||
|
#else
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Yap_InitBigNums(void)
|
Yap_InitBigNums(void)
|
||||||
{
|
{
|
||||||
Yap_InitCPred("$has_bignums", 0, p_has_bignums, SafePredFlag|HiddenPredFlag);
|
Yap_InitCPred("$has_bignums", 0, p_has_bignums, SafePredFlag|HiddenPredFlag);
|
||||||
Yap_InitCPred("$bignum", 1, p_is_bignum, SafePredFlag|HiddenPredFlag);
|
Yap_InitCPred("$bignum", 1, p_is_bignum, SafePredFlag|HiddenPredFlag);
|
||||||
|
Yap_InitCPred("rational", 3, p_rational, 0);
|
||||||
|
Yap_InitCPred("rational", 1, p_is_rational, SafePredFlag);
|
||||||
}
|
}
|
||||||
|
@ -398,7 +398,8 @@ copy_complex_term(register CELL *pt0, register CELL *pt0_end, int share, int cop
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/* big int */
|
/* big int */
|
||||||
UInt sz = ArenaSz(d0), i;
|
UInt sz = (sizeof(MP_INT)+3*CellSize+
|
||||||
|
((MP_INT *)(ap2+2))->_mp_alloc*sizeof(mp_limb_t))/CellSize, i;
|
||||||
|
|
||||||
if (H > ASP - (MIN_ARENA_SIZE+sz)) {
|
if (H > ASP - (MIN_ARENA_SIZE+sz)) {
|
||||||
goto overflow;
|
goto overflow;
|
||||||
|
346
C/gmp_support.c
346
C/gmp_support.c
@ -462,10 +462,13 @@ Yap_gmp_mul_big_big(Term t1, Term t2)
|
|||||||
MP_RAT new;
|
MP_RAT new;
|
||||||
MP_RAT *b1, bb1;
|
MP_RAT *b1, bb1;
|
||||||
MP_RAT *b2, bb2;
|
MP_RAT *b2, bb2;
|
||||||
|
int f1 = FALSE, f2 = FALSE;
|
||||||
|
|
||||||
if (pt1[1] == BIG_INT) {
|
if (pt1[1] == BIG_INT) {
|
||||||
b1 = &bb1;
|
b1 = &bb1;
|
||||||
mpq_init(b1);
|
mpq_init(b1);
|
||||||
mpq_set_z(b1, Yap_BigIntOfTerm(t1));
|
mpq_set_z(b1, Yap_BigIntOfTerm(t1));
|
||||||
|
f1 = TRUE;
|
||||||
} else {
|
} else {
|
||||||
b1 = Yap_BigRatOfTerm(t1);
|
b1 = Yap_BigRatOfTerm(t1);
|
||||||
}
|
}
|
||||||
@ -473,11 +476,14 @@ Yap_gmp_mul_big_big(Term t1, Term t2)
|
|||||||
b2 = &bb2;
|
b2 = &bb2;
|
||||||
mpq_init(b2);
|
mpq_init(b2);
|
||||||
mpq_set_z(b2, Yap_BigIntOfTerm(t2));
|
mpq_set_z(b2, Yap_BigIntOfTerm(t2));
|
||||||
|
f2 = TRUE;
|
||||||
} else {
|
} else {
|
||||||
b2 = Yap_BigRatOfTerm(t2);
|
b2 = Yap_BigRatOfTerm(t2);
|
||||||
}
|
}
|
||||||
mpq_init(&new);
|
mpq_init(&new);
|
||||||
mpq_mul(&new, b1, b2);
|
mpq_mul(&new, b1, b2);
|
||||||
|
if (f1) mpq_clear(b1);
|
||||||
|
if (f2) mpq_clear(b2);
|
||||||
return MkRatAndClose(&new);
|
return MkRatAndClose(&new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -751,6 +757,15 @@ Yap_gmp_gcd_int_big(Int i, Term t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_float_to_big(Float v)
|
||||||
|
{
|
||||||
|
MP_INT new;
|
||||||
|
|
||||||
|
mpz_init_set_d(&new, v);
|
||||||
|
return MkBigAndClose(&new);
|
||||||
|
}
|
||||||
|
|
||||||
Float
|
Float
|
||||||
Yap_gmp_to_float(Term t)
|
Yap_gmp_to_float(Term t)
|
||||||
{
|
{
|
||||||
@ -939,6 +954,10 @@ Yap_gmq_rdiv_int_int(Int i1, Int i2)
|
|||||||
MP_RAT new;
|
MP_RAT new;
|
||||||
|
|
||||||
mpq_init(&new);
|
mpq_init(&new);
|
||||||
|
if (i2 < 0) {
|
||||||
|
i1 = -i1;
|
||||||
|
i2 = -i2;
|
||||||
|
}
|
||||||
mpq_set_si(&new, i1, i2);
|
mpq_set_si(&new, i1, i2);
|
||||||
mpq_canonicalize(&new);
|
mpq_canonicalize(&new);
|
||||||
return MkRatAndClose(&new);
|
return MkRatAndClose(&new);
|
||||||
@ -947,46 +966,77 @@ Yap_gmq_rdiv_int_int(Int i1, Int i2)
|
|||||||
Term
|
Term
|
||||||
Yap_gmq_rdiv_int_big(Int i1, Term t2)
|
Yap_gmq_rdiv_int_big(Int i1, Term t2)
|
||||||
{
|
{
|
||||||
MP_RAT new, new2;
|
MP_RAT new;
|
||||||
MP_INT *b = Yap_BigIntOfTerm(t2);
|
CELL *pt2 = RepAppl(t2);
|
||||||
|
|
||||||
mpq_init(&new);
|
mpq_init(&new);
|
||||||
mpq_set_si(&new, i1, 1L);
|
mpq_set_si(&new, i1, 1L);
|
||||||
mpq_init(&new2);
|
if (pt2[1] == BIG_INT) {
|
||||||
mpq_set_z(&new2, b);
|
MP_RAT new2;
|
||||||
mpq_div(&new,&new,&new2);
|
MP_INT *b = Yap_BigIntOfTerm(t2);
|
||||||
mpq_clear(&new2);
|
|
||||||
|
mpq_init(&new2);
|
||||||
|
mpq_set_z(&new2, b);
|
||||||
|
mpq_div(&new,&new,&new2);
|
||||||
|
mpq_clear(&new2);
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t2);
|
||||||
|
mpq_div(&new,&new,b);
|
||||||
|
}
|
||||||
return MkRatAndClose(&new);
|
return MkRatAndClose(&new);
|
||||||
}
|
}
|
||||||
|
|
||||||
Term
|
Term
|
||||||
Yap_gmq_rdiv_big_int(Term t1, Int i2)
|
Yap_gmq_rdiv_big_int(Term t1, Int i2)
|
||||||
{
|
{
|
||||||
MP_RAT new, new2;
|
MP_RAT new;
|
||||||
MP_INT *b = Yap_BigIntOfTerm(t1);
|
CELL *pt1 = RepAppl(t1);
|
||||||
|
|
||||||
mpq_init(&new);
|
mpq_init(&new);
|
||||||
mpq_set_si(&new, i2, 1L);
|
mpq_set_si(&new, i2, 1L);
|
||||||
mpq_init(&new2);
|
if (pt1[1] == BIG_INT) {
|
||||||
mpq_set_z(&new2, b);
|
MP_INT *b = Yap_BigIntOfTerm(t1);
|
||||||
mpq_div(&new,&new2,&new);
|
MP_RAT new2;
|
||||||
mpq_clear(&new2);
|
|
||||||
|
mpq_init(&new2);
|
||||||
|
mpq_set_z(&new2, b);
|
||||||
|
mpq_div(&new,&new2,&new);
|
||||||
|
mpq_clear(&new2);
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t1);
|
||||||
|
|
||||||
|
mpq_div(&new,b,&new);
|
||||||
|
}
|
||||||
return MkRatAndClose(&new);
|
return MkRatAndClose(&new);
|
||||||
}
|
}
|
||||||
|
|
||||||
Term
|
Term
|
||||||
Yap_gmq_rdiv_big_big(Term t1, Term t2)
|
Yap_gmq_rdiv_big_big(Term t1, Term t2)
|
||||||
{
|
{
|
||||||
MP_RAT new, new2;
|
MP_RAT new;
|
||||||
MP_INT *b1 = Yap_BigIntOfTerm(t1);
|
CELL *pt1 = RepAppl(t1);
|
||||||
MP_INT *b2 = Yap_BigIntOfTerm(t2);
|
CELL *pt2 = RepAppl(t2);
|
||||||
|
|
||||||
mpq_init(&new);
|
mpq_init(&new);
|
||||||
mpq_set_z(&new, b1);
|
if (pt1[1] == BIG_INT) {
|
||||||
mpq_init(&new2);
|
MP_INT *b1 = Yap_BigIntOfTerm(t1);
|
||||||
mpq_set_z(&new2, b2);
|
mpq_set_z(&new, b1);
|
||||||
mpq_div(&new,&new,&new2);
|
} else {
|
||||||
mpq_clear(&new2);
|
MP_RAT *b1 = Yap_BigRatOfTerm(t1);
|
||||||
|
mpq_set(&new, b1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pt2[1] == BIG_INT) {
|
||||||
|
MP_RAT new2;
|
||||||
|
MP_INT *b2 = Yap_BigIntOfTerm(t2);
|
||||||
|
|
||||||
|
mpq_init(&new2);
|
||||||
|
mpq_set_z(&new2, b2);
|
||||||
|
mpq_div(&new,&new,&new2);
|
||||||
|
mpq_clear(&new2);
|
||||||
|
} else {
|
||||||
|
MP_RAT *b2 = Yap_BigRatOfTerm(t2);
|
||||||
|
mpq_div(&new,&new,b2);
|
||||||
|
}
|
||||||
return MkRatAndClose(&new);
|
return MkRatAndClose(&new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1157,13 +1207,82 @@ Yap_gmp_neg_big(Term t)
|
|||||||
return MkBigAndClose(&new);
|
return MkBigAndClose(&new);
|
||||||
} else {
|
} else {
|
||||||
MP_RAT *b = Yap_BigRatOfTerm(t);
|
MP_RAT *b = Yap_BigRatOfTerm(t);
|
||||||
MP_INT new;
|
MP_RAT new;
|
||||||
mpq_init(&new);
|
mpq_init(&new);
|
||||||
mpq_neg(&new, b);
|
mpq_neg(&new, b);
|
||||||
return MkRatAndClose(&new);
|
return MkRatAndClose(&new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_float_to_rational(Float dbl)
|
||||||
|
{
|
||||||
|
MP_RAT new;
|
||||||
|
mpq_init(&new);
|
||||||
|
mpq_set_d(&new, dbl);
|
||||||
|
return MkRatAndClose(&new);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
A is rationalize(Float)
|
||||||
|
|
||||||
|
Introduced on the suggestion of Richard O'Keefe after the Common Lisp
|
||||||
|
standard. The algorithm is taken from figure 3 in ``A Rational Rotation
|
||||||
|
Method for Robust Geometric Algorithms'' by John Canny, Bruce Donald and
|
||||||
|
Eugene K. Ressler. Found at
|
||||||
|
|
||||||
|
http://www.cs.dartmouth.edu/~brd/papers/rotations-scg92.pdf
|
||||||
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
|
#ifndef DBL_EPSILON /* normal for IEEE 64-bit double */
|
||||||
|
#define DBL_EPSILON 0.00000000000000022204
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_float_rationalize(Float dbl)
|
||||||
|
{
|
||||||
|
Float e0 = dbl, p0 = 0.0, q0 = 1.0;
|
||||||
|
Float e1 = -1.0, p1 = 1.0, q1 = 0.0;
|
||||||
|
Float d;
|
||||||
|
MP_RAT new;
|
||||||
|
|
||||||
|
do { Float r = floor(e0/e1);
|
||||||
|
Float e00 = e0, p00 = p0, q00 = q0;
|
||||||
|
e0 = e1;
|
||||||
|
p0 = p1;
|
||||||
|
q0 = q1;
|
||||||
|
e1 = e00 - r*e1;
|
||||||
|
p1 = p00 - r*p1;
|
||||||
|
q1 = q00 - r*q1;
|
||||||
|
|
||||||
|
d = p1/q1 - dbl;
|
||||||
|
} while(fabs(d) > DBL_EPSILON);
|
||||||
|
|
||||||
|
mpz_init_set_d(mpq_numref(&new), p1);
|
||||||
|
mpz_init_set_d(mpq_denref(&new), q1);
|
||||||
|
mpq_canonicalize(&new); /* is this needed? */
|
||||||
|
return MkRatAndClose(&new);
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_abs_big(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
MP_INT *b = Yap_BigIntOfTerm(t);
|
||||||
|
MP_INT new;
|
||||||
|
mpz_init_set(&new, b);
|
||||||
|
mpz_abs(&new, &new);
|
||||||
|
return MkBigAndClose(&new);
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t);
|
||||||
|
MP_RAT new;
|
||||||
|
mpq_init(&new);
|
||||||
|
mpq_abs(&new, b);
|
||||||
|
return MkRatAndClose(&new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Term
|
Term
|
||||||
Yap_gmp_unot_big(Term t)
|
Yap_gmp_unot_big(Term t)
|
||||||
{
|
{
|
||||||
@ -1179,6 +1298,189 @@ Yap_gmp_unot_big(Term t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_floor(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
return t;
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t);
|
||||||
|
MP_INT new;
|
||||||
|
mpz_init(&new);
|
||||||
|
mpz_set_q(&new, b);
|
||||||
|
if (mpq_sgn(b) < 0 && mpz_cmp_si(mpq_denref(b),1L) != 0) {
|
||||||
|
mpz_sub_ui(&new,&new,1L);
|
||||||
|
}
|
||||||
|
return MkBigAndClose(&new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_ceiling(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
return t;
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t);
|
||||||
|
MP_INT new;
|
||||||
|
mpz_init(&new);
|
||||||
|
mpz_set_q(&new, b);
|
||||||
|
if (mpq_sgn(b) > 0 && mpz_cmp_si(mpq_denref(b),1L) != 0) {
|
||||||
|
mpz_add_ui(&new,&new,1L);
|
||||||
|
}
|
||||||
|
return MkBigAndClose(&new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_round(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
return t;
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t);
|
||||||
|
MP_INT new;
|
||||||
|
MP_RAT half, q;
|
||||||
|
|
||||||
|
mpq_init(&half);
|
||||||
|
mpq_init(&q);
|
||||||
|
mpq_set_ui(&half, 1, 2); /* 1/2 */
|
||||||
|
if ( mpq_sgn(b) > 0 )
|
||||||
|
mpq_add(&q, b, &half);
|
||||||
|
else {
|
||||||
|
mpq_sub(&q, b, &half);
|
||||||
|
}
|
||||||
|
mpz_init(&new);
|
||||||
|
mpz_set_q(&new, &q);
|
||||||
|
mpq_clear(&half);
|
||||||
|
mpq_clear(&q);
|
||||||
|
return MkBigAndClose(&new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_trunc(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
return t;
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t);
|
||||||
|
MP_INT new;
|
||||||
|
int sgn = mpq_sgn(b);
|
||||||
|
|
||||||
|
if (sgn)
|
||||||
|
mpq_neg(b, b);
|
||||||
|
mpz_init(&new);
|
||||||
|
mpz_set_q(&new, b);
|
||||||
|
if (sgn) {
|
||||||
|
mpq_neg(b, b);
|
||||||
|
mpz_neg(&new, &new);
|
||||||
|
}
|
||||||
|
return MkBigAndClose(&new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_float_fractional_part(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is float_fractional_part(%f)", FloatOfTerm(t));
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t);
|
||||||
|
MP_RAT new;
|
||||||
|
|
||||||
|
mpq_init(&new);
|
||||||
|
mpz_tdiv_q(mpq_numref(&new),
|
||||||
|
mpq_numref(b),
|
||||||
|
mpq_denref(b));
|
||||||
|
mpz_set_ui(mpq_denref(&new), 1);
|
||||||
|
mpq_sub(&new, b, &new);
|
||||||
|
return MkRatAndClose(&new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_float_integer_part(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
return Yap_ArithError(TYPE_ERROR_FLOAT, t, "X is float_integer_part(%f)", FloatOfTerm(t));
|
||||||
|
} else {
|
||||||
|
MP_RAT *b = Yap_BigRatOfTerm(t);
|
||||||
|
MP_INT new;
|
||||||
|
|
||||||
|
mpz_init(&new);
|
||||||
|
mpz_tdiv_q(&new,
|
||||||
|
mpq_numref(b),
|
||||||
|
mpq_denref(b));
|
||||||
|
return MkBigAndClose(&new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_sign(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
return MkIntegerTerm(mpz_sgn(Yap_BigIntOfTerm(t)));
|
||||||
|
} else {
|
||||||
|
return MkIntegerTerm(mpq_sgn(Yap_BigRatOfTerm(t)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_lsb(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
MP_INT *big = Yap_BigIntOfTerm(t);
|
||||||
|
if ( mpz_sgn(big) <= 0 ) {
|
||||||
|
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t,
|
||||||
|
"lsb/1 received negative bignum");
|
||||||
|
}
|
||||||
|
return MkIntegerTerm(mpz_scan1(big,0));
|
||||||
|
} else {
|
||||||
|
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "lsb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_msb(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
MP_INT *big = Yap_BigIntOfTerm(t);
|
||||||
|
if ( mpz_sgn(big) <= 0 ) {
|
||||||
|
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t,
|
||||||
|
"msb/1 received negative bignum");
|
||||||
|
}
|
||||||
|
return MkIntegerTerm(mpz_sizeinbase(big,2));
|
||||||
|
} else {
|
||||||
|
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "popcount");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Term
|
||||||
|
Yap_gmp_popcount(Term t)
|
||||||
|
{
|
||||||
|
CELL *pt = RepAppl(t);
|
||||||
|
if (pt[1] == BIG_INT) {
|
||||||
|
MP_INT *big = Yap_BigIntOfTerm(t);
|
||||||
|
if ( mpz_sgn(big) <= 0 ) {
|
||||||
|
return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t,
|
||||||
|
"popcount/1 received negative bignum");
|
||||||
|
}
|
||||||
|
return MkIntegerTerm(mpz_popcount(big));
|
||||||
|
} else {
|
||||||
|
return Yap_ArithError(TYPE_ERROR_INTEGER, t, "popcount");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
75
C/write.c
75
C/write.c
@ -191,7 +191,6 @@ write_mpq(MP_RAT *q, wrf writewch) {
|
|||||||
char *s;
|
char *s;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
fprintf(stderr,"%ld %ld\n",mpz_sizeinbase (mpq_numref(q), 10),mpz_sizeinbase (mpq_denref(q), 10));
|
|
||||||
sz = ((size_t)3) +mpz_sizeinbase(mpq_numref(q), 10)+ mpz_sizeinbase (mpq_denref(q), 10);
|
sz = ((size_t)3) +mpz_sizeinbase(mpq_numref(q), 10)+ mpz_sizeinbase (mpq_denref(q), 10);
|
||||||
s = ensure_space(sz);
|
s = ensure_space(sz);
|
||||||
if (mpq_sgn(q) < 0) {
|
if (mpq_sgn(q) < 0) {
|
||||||
@ -214,23 +213,24 @@ write_mpq(MP_RAT *q, wrf writewch) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* writes a bignum */
|
||||||
static void
|
static void
|
||||||
writebig(Term t, wrf writewch) /* writes an integer */
|
writebig(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, struct rewind_term *rwt)
|
||||||
{
|
{
|
||||||
#ifdef USE_GMP
|
#ifdef USE_GMP
|
||||||
CELL *pt = RepAppl(t)+1;
|
CELL *pt = RepAppl(t)+1;
|
||||||
if (pt[0] == BIG_INT)
|
if (pt[0] == BIG_INT)
|
||||||
{
|
{
|
||||||
MP_INT *big = Yap_BigIntOfTerm(t);
|
MP_INT *big = Yap_BigIntOfTerm(t);
|
||||||
write_mpint(big, writewch);
|
write_mpint(big, wglb->writewch);
|
||||||
return;
|
return;
|
||||||
} else if (pt[0] == BIG_RATIONAL) {
|
} else if (pt[0] == BIG_RATIONAL) {
|
||||||
MP_RAT *q = Yap_BigRatOfTerm(t);
|
Term trat = Yap_RatTermToApplTerm(t);
|
||||||
write_mpq(q, writewch);
|
writeTerm(trat, p, depth, rinfixarg, wglb, rwt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
wrputs("0",writewch);
|
wrputs("0",wglb->writewch);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -739,66 +739,9 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str
|
|||||||
case (CELL)FunctorLongInt:
|
case (CELL)FunctorLongInt:
|
||||||
wrputn(LongIntOfTerm(t),wglb->writewch);
|
wrputn(LongIntOfTerm(t),wglb->writewch);
|
||||||
return;
|
return;
|
||||||
case (CELL)FunctorBigInt:
|
/* case (CELL)FunctorBigInt: */
|
||||||
writebig(t,wglb->writewch);
|
default:
|
||||||
return;
|
writebig(t, p, depth, rinfixarg, wglb, rwt);
|
||||||
#ifdef USE_GMP
|
|
||||||
{
|
|
||||||
MP_INT *big = Yap_BigIntOfTerm(t);
|
|
||||||
char *s;
|
|
||||||
s = (char *) Yap_PreAllocCodeSpace();
|
|
||||||
while (s+3+mpz_sizeinbase(big, 10) >= (char *)AuxSp) {
|
|
||||||
#if USE_SYSTEM_MALLOC
|
|
||||||
/* may require stack expansion */
|
|
||||||
if (!Yap_ExpandPreAllocCodeSpace(3+mpz_sizeinbase(big, 10), NULL, TRUE)) {
|
|
||||||
s = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
s = (char *) Yap_PreAllocCodeSpace();
|
|
||||||
#else
|
|
||||||
s = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (!s) {
|
|
||||||
s = (char *)TR;
|
|
||||||
while (s+3+mpz_sizeinbase(big, 10) >= Yap_TrailTop) {
|
|
||||||
if (!Yap_growtrail((3+mpz_sizeinbase(big, 10))/sizeof(CELL), FALSE)) {
|
|
||||||
s = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
s = (char *)TR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!s) {
|
|
||||||
s = (char *)H;
|
|
||||||
if (s+3+mpz_sizeinbase(big, 10) >= (char *)ASP) {
|
|
||||||
Yap_Error(OUT_OF_STACK_ERROR,TermNil,"not enough space to write bignum: it requires %d bytes", 3+mpz_sizeinbase(big, 10));
|
|
||||||
s = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mpz_sgn(big) < 0) {
|
|
||||||
if (lastw == symbol)
|
|
||||||
wrputc(' ', wglb->writewch);
|
|
||||||
} else {
|
|
||||||
if (lastw == alphanum)
|
|
||||||
wrputc(' ', wglb->writewch);
|
|
||||||
}
|
|
||||||
if (!s) {
|
|
||||||
s = mpz_get_str(NULL, 10, big);
|
|
||||||
if (!s)
|
|
||||||
return;
|
|
||||||
wrputs(s,wglb->writewch);
|
|
||||||
free(s);
|
|
||||||
} else {
|
|
||||||
mpz_get_str(s, 10, big);
|
|
||||||
wrputs(s,wglb->writewch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
wrputs("0",wglb->writewch);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,8 +117,9 @@ void STD_PROTO(Yap_InitAttVarPreds,(void));
|
|||||||
void STD_PROTO(Yap_InitBBPreds,(void));
|
void STD_PROTO(Yap_InitBBPreds,(void));
|
||||||
|
|
||||||
/* bignum.c */
|
/* bignum.c */
|
||||||
Term STD_PROTO(Yap_MkULLIntTerm,(YAP_ULONG_LONG));
|
Term STD_PROTO(Yap_MkULLIntTerm, (YAP_ULONG_LONG));
|
||||||
void STD_PROTO(Yap_InitBigNums,(void));
|
Term STD_PROTO(Yap_RatTermToApplTerm, (Term));
|
||||||
|
void STD_PROTO(Yap_InitBigNums, (void));
|
||||||
|
|
||||||
/* c_interface.c */
|
/* c_interface.c */
|
||||||
Int STD_PROTO(YAP_Execute,(struct pred_entry *, CPredicate));
|
Int STD_PROTO(YAP_Execute,(struct pred_entry *, CPredicate));
|
||||||
|
16
H/eval.h
16
H/eval.h
@ -95,6 +95,8 @@ typedef enum {
|
|||||||
op_lgamma,
|
op_lgamma,
|
||||||
op_erf,
|
op_erf,
|
||||||
op_erfc,
|
op_erfc,
|
||||||
|
op_rational,
|
||||||
|
op_rationalize,
|
||||||
op_random1
|
op_random1
|
||||||
} arith1_op;
|
} arith1_op;
|
||||||
|
|
||||||
@ -263,6 +265,9 @@ Term STD_PROTO(Yap_gmp_gcd_big_big,(Term,Term));
|
|||||||
|
|
||||||
Term STD_PROTO(Yap_gmp_big_from_64bits,(YAP_LONG_LONG));
|
Term STD_PROTO(Yap_gmp_big_from_64bits,(YAP_LONG_LONG));
|
||||||
|
|
||||||
|
Term STD_PROTO(Yap_gmp_float_to_big,(Float));
|
||||||
|
Term STD_PROTO(Yap_gmp_float_to_rational,(Float));
|
||||||
|
Term STD_PROTO(Yap_gmp_float_rationalize,(Float));
|
||||||
Float STD_PROTO(Yap_gmp_to_float,(Term));
|
Float STD_PROTO(Yap_gmp_to_float,(Term));
|
||||||
Term STD_PROTO(Yap_gmp_add_float_big,(Float, Term));
|
Term STD_PROTO(Yap_gmp_add_float_big,(Float, Term));
|
||||||
Term STD_PROTO(Yap_gmp_sub_float_big,(Float, Term));
|
Term STD_PROTO(Yap_gmp_sub_float_big,(Float, Term));
|
||||||
@ -278,8 +283,19 @@ int STD_PROTO(Yap_gmp_cmp_big_float,(Term, Float));
|
|||||||
int STD_PROTO(Yap_gmp_cmp_big_big,(Term, Term));
|
int STD_PROTO(Yap_gmp_cmp_big_big,(Term, Term));
|
||||||
|
|
||||||
Term STD_PROTO(Yap_gmp_neg_int,(Int));
|
Term STD_PROTO(Yap_gmp_neg_int,(Int));
|
||||||
|
Term STD_PROTO(Yap_gmp_abs_big,(Term));
|
||||||
Term STD_PROTO(Yap_gmp_neg_big,(Term));
|
Term STD_PROTO(Yap_gmp_neg_big,(Term));
|
||||||
Term STD_PROTO(Yap_gmp_unot_big,(Term));
|
Term STD_PROTO(Yap_gmp_unot_big,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_floor,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_ceiling,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_round,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_trunc,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_float_fractional_part,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_float_integer_part,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_sign,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_lsb,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_msb,(Term));
|
||||||
|
Term STD_PROTO(Yap_gmp_popcount,(Term));
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -226,6 +226,7 @@
|
|||||||
AtomRepeatSpace = Yap_LookupAtom("repeat ");
|
AtomRepeatSpace = Yap_LookupAtom("repeat ");
|
||||||
AtomReposition = Yap_LookupAtom("reposition");
|
AtomReposition = Yap_LookupAtom("reposition");
|
||||||
AtomRepresentationError = Yap_LookupAtom("representation_error");
|
AtomRepresentationError = Yap_LookupAtom("representation_error");
|
||||||
|
AtomRDiv = Yap_LookupAtom("rdiv");
|
||||||
AtomResize = Yap_LookupAtom("resize");
|
AtomResize = Yap_LookupAtom("resize");
|
||||||
AtomResourceError = Yap_LookupAtom("resource_error");
|
AtomResourceError = Yap_LookupAtom("resource_error");
|
||||||
AtomRestoreRegs = Yap_FullLookupAtom("$restore_regs");
|
AtomRestoreRegs = Yap_FullLookupAtom("$restore_regs");
|
||||||
@ -389,6 +390,7 @@
|
|||||||
FunctorPrologConstraint = Yap_MkFunctor(AtomProlog,2);
|
FunctorPrologConstraint = Yap_MkFunctor(AtomProlog,2);
|
||||||
FunctorQuery = Yap_MkFunctor(AtomQuery,1);
|
FunctorQuery = Yap_MkFunctor(AtomQuery,1);
|
||||||
FunctorRecordedWithKey = Yap_MkFunctor(AtomRecordedWithKey,6);
|
FunctorRecordedWithKey = Yap_MkFunctor(AtomRecordedWithKey,6);
|
||||||
|
FunctorRDiv = Yap_MkFunctor(AtomRDiv,2);
|
||||||
FunctorRedoFreeze = Yap_MkFunctor(AtomRedoFreeze,3);
|
FunctorRedoFreeze = Yap_MkFunctor(AtomRedoFreeze,3);
|
||||||
FunctorRepresentationError = Yap_MkFunctor(AtomRepresentationError,1);
|
FunctorRepresentationError = Yap_MkFunctor(AtomRepresentationError,1);
|
||||||
FunctorResourceError = Yap_MkFunctor(AtomResourceError,1);
|
FunctorResourceError = Yap_MkFunctor(AtomResourceError,1);
|
||||||
|
@ -226,6 +226,7 @@
|
|||||||
AtomRepeatSpace = AtomAdjust(AtomRepeatSpace);
|
AtomRepeatSpace = AtomAdjust(AtomRepeatSpace);
|
||||||
AtomReposition = AtomAdjust(AtomReposition);
|
AtomReposition = AtomAdjust(AtomReposition);
|
||||||
AtomRepresentationError = AtomAdjust(AtomRepresentationError);
|
AtomRepresentationError = AtomAdjust(AtomRepresentationError);
|
||||||
|
AtomRDiv = AtomAdjust(AtomRDiv);
|
||||||
AtomResize = AtomAdjust(AtomResize);
|
AtomResize = AtomAdjust(AtomResize);
|
||||||
AtomResourceError = AtomAdjust(AtomResourceError);
|
AtomResourceError = AtomAdjust(AtomResourceError);
|
||||||
AtomRestoreRegs = AtomAdjust(AtomRestoreRegs);
|
AtomRestoreRegs = AtomAdjust(AtomRestoreRegs);
|
||||||
@ -389,6 +390,7 @@
|
|||||||
FunctorPrologConstraint = FuncAdjust(FunctorPrologConstraint);
|
FunctorPrologConstraint = FuncAdjust(FunctorPrologConstraint);
|
||||||
FunctorQuery = FuncAdjust(FunctorQuery);
|
FunctorQuery = FuncAdjust(FunctorQuery);
|
||||||
FunctorRecordedWithKey = FuncAdjust(FunctorRecordedWithKey);
|
FunctorRecordedWithKey = FuncAdjust(FunctorRecordedWithKey);
|
||||||
|
FunctorRDiv = FuncAdjust(FunctorRDiv);
|
||||||
FunctorRedoFreeze = FuncAdjust(FunctorRedoFreeze);
|
FunctorRedoFreeze = FuncAdjust(FunctorRedoFreeze);
|
||||||
FunctorRepresentationError = FuncAdjust(FunctorRepresentationError);
|
FunctorRepresentationError = FuncAdjust(FunctorRepresentationError);
|
||||||
FunctorResourceError = FuncAdjust(FunctorResourceError);
|
FunctorResourceError = FuncAdjust(FunctorResourceError);
|
||||||
|
@ -450,6 +450,8 @@
|
|||||||
#define AtomReposition Yap_heap_regs->AtomReposition_
|
#define AtomReposition Yap_heap_regs->AtomReposition_
|
||||||
Atom AtomRepresentationError_;
|
Atom AtomRepresentationError_;
|
||||||
#define AtomRepresentationError Yap_heap_regs->AtomRepresentationError_
|
#define AtomRepresentationError Yap_heap_regs->AtomRepresentationError_
|
||||||
|
Atom AtomRDiv_;
|
||||||
|
#define AtomRDiv Yap_heap_regs->AtomRDiv_
|
||||||
Atom AtomResize_;
|
Atom AtomResize_;
|
||||||
#define AtomResize Yap_heap_regs->AtomResize_
|
#define AtomResize Yap_heap_regs->AtomResize_
|
||||||
Atom AtomResourceError_;
|
Atom AtomResourceError_;
|
||||||
@ -776,6 +778,8 @@
|
|||||||
#define FunctorQuery Yap_heap_regs->FunctorQuery_
|
#define FunctorQuery Yap_heap_regs->FunctorQuery_
|
||||||
Functor FunctorRecordedWithKey_;
|
Functor FunctorRecordedWithKey_;
|
||||||
#define FunctorRecordedWithKey Yap_heap_regs->FunctorRecordedWithKey_
|
#define FunctorRecordedWithKey Yap_heap_regs->FunctorRecordedWithKey_
|
||||||
|
Functor FunctorRDiv_;
|
||||||
|
#define FunctorRDiv Yap_heap_regs->FunctorRDiv_
|
||||||
Functor FunctorRedoFreeze_;
|
Functor FunctorRedoFreeze_;
|
||||||
#define FunctorRedoFreeze Yap_heap_regs->FunctorRedoFreeze_
|
#define FunctorRedoFreeze Yap_heap_regs->FunctorRedoFreeze_
|
||||||
Functor FunctorRepresentationError_;
|
Functor FunctorRepresentationError_;
|
||||||
|
@ -231,6 +231,7 @@ A Repeat N "repeat"
|
|||||||
A RepeatSpace N "repeat "
|
A RepeatSpace N "repeat "
|
||||||
A Reposition N "reposition"
|
A Reposition N "reposition"
|
||||||
A RepresentationError N "representation_error"
|
A RepresentationError N "representation_error"
|
||||||
|
A RDiv N "rdiv"
|
||||||
A Resize N "resize"
|
A Resize N "resize"
|
||||||
A ResourceError N "resource_error"
|
A ResourceError N "resource_error"
|
||||||
A RestoreRegs F "$restore_regs"
|
A RestoreRegs F "$restore_regs"
|
||||||
@ -394,6 +395,7 @@ F Portray Portray 1
|
|||||||
F PrologConstraint Prolog 2
|
F PrologConstraint Prolog 2
|
||||||
F Query Query 1
|
F Query Query 1
|
||||||
F RecordedWithKey RecordedWithKey 6
|
F RecordedWithKey RecordedWithKey 6
|
||||||
|
F RDiv RDiv 2
|
||||||
F RedoFreeze RedoFreeze 3
|
F RedoFreeze RedoFreeze 3
|
||||||
F RepresentationError RepresentationError 1
|
F RepresentationError RepresentationError 1
|
||||||
F ResourceError ResourceError 1
|
F ResourceError ResourceError 1
|
||||||
|
Reference in New Issue
Block a user