diff --git a/C/arith1.c b/C/arith1.c index 2a3d413b9..fa2d2cf21 100755 --- a/C/arith1.c +++ b/C/arith1.c @@ -218,11 +218,7 @@ eval1(Int fi, Term t) { Int i = IntegerOfTerm(t); if (i == Int_MIN) { - MP_INT new; - - mpz_init_set_si(&new, i); - mpz_neg(&new, &new); - RBIG(&new); + return Yap_gmp_neg_int(i); } else #endif @@ -231,15 +227,7 @@ eval1(Int fi, Term t) { case double_e: RFLOAT(-FloatOfTerm(t)); case big_int_e: -#ifdef USE_GMP - { - MP_INT new; - - mpz_init_set(&new, Yap_BigIntOfTerm(t)); - mpz_neg(&new, &new); - RBIG(&new); - } -#endif + return Yap_gmp_neg_big(t); default: RERROR(); } @@ -248,16 +236,10 @@ eval1(Int fi, Term t) { case long_int_e: RINT(~IntegerOfTerm(t)); case double_e: - return Yap_ArithError(TYPE_ERROR_INTEGER, t, "\\(f)", FloatOfTerm(t)); + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "\\(%f)", FloatOfTerm(t)); case big_int_e: #ifdef USE_GMP - { - MP_INT new; - - mpz_init_set(&new, Yap_BigIntOfTerm(t)); - mpz_com(&new, &new); - RBIG(&new); - } + return Yap_gmp_unot_big(t); #endif default: RERROR(); diff --git a/C/arith2.c b/C/arith2.c index a5fad8ecb..a00aa5911 100755 --- a/C/arith2.c +++ b/C/arith2.c @@ -36,31 +36,6 @@ typedef struct init_un_eval { } InitBinEntry; -#ifdef USE_GMP -static Float -fdiv_bigint(MP_INT *b1,MP_INT *b2) -{ - Float f1 = mpz_get_d(b1); - Float f2 = mpz_get_d(b2); - if (1) { - mpf_t f1,f2; - Float res; - - mpf_init(f1); - mpf_init(f2); - mpf_set_z(f1, b1); - mpf_set_z(f2, b2); - mpf_div(f1, f1, f2); - res = mpf_get_d(f1); - mpf_clear(f1); - mpf_clear(f2); - return(res); - } else { - return(f1/f2); - } -} -#endif - static Term p_mod(Term t1, Term t2) { switch (ETypeOfTerm(t1)) { @@ -91,7 +66,7 @@ p_mod(Term t1, Term t2) { return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); case (CELL)big_int_e: #ifdef USE_GMP - return Yap_gmp_mod_int_big(IntegerOfTerm(t1), Yap_BigIntOfTerm(t2)); + return Yap_gmp_mod_int_big(IntegerOfTerm(t1), t2); #endif default: RERROR(); @@ -108,11 +83,11 @@ p_mod(Term t1, Term t2) { Int i2 = IntegerOfTerm(t2); if (i2 == 0) goto zero_divisor; - return Yap_gmp_mod_big_int(Yap_BigIntOfTerm(t1), i2); + return Yap_gmp_mod_big_int(t1, i2); } case (CELL)big_int_e: /* two bignums */ - return Yap_gmp_mod_big_big(Yap_BigIntOfTerm(t1), Yap_BigIntOfTerm(t2)); + return Yap_gmp_mod_big_big(t1, t2); case double_e: return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); default: @@ -154,8 +129,7 @@ p_rem(Term t1, Term t2) { return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); case (CELL)big_int_e: #ifdef USE_GMP - /* I know the term is much larger, so: */ - RINT(IntegerOfTerm(t1)); + return Yap_gmp_rem_int_big(IntegerOfTerm(t1), t2); #endif default: RERROR(); @@ -167,28 +141,57 @@ p_rem(Term t1, Term t2) { #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - /* modulo between bignum and integer */ + return Yap_gmp_rem_big_int(t1, IntegerOfTerm(t2)); + case (CELL)big_int_e: + /* two bignums */ + return Yap_gmp_rem_big_big(t1, t2); + case double_e: + return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); + default: + RERROR(); + } +#endif + default: + RERROR(); + } + zero_divisor: + return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, t2, "X is mod 0"); +} + + +static Term +p_rdiv(Term t1, Term t2) { + switch (ETypeOfTerm(t1)) { + case (CELL)double_e: + return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "rdiv/2"); +#ifdef USE_GMP + case (CELL)long_int_e: + switch (ETypeOfTerm(t2)) { + case (CELL)long_int_e: + /* two integers */ { - mpz_t tmp; - MP_INT new; + Int i1 = IntegerOfTerm(t1); Int i2 = IntegerOfTerm(t2); if (i2 == 0) goto zero_divisor; - mpz_init(&new); - mpz_init_set_si(tmp, i2); - mpz_tdiv_r(&new, Yap_BigIntOfTerm(t1), tmp); - mpz_clear(tmp); - RBIG(&new); + return Yap_gmq_rdiv_int_int(i1, i2); } case (CELL)big_int_e: - /* two bignums */ - { - MP_INT new; - - mpz_init(&new); - mpz_tdiv_r(&new, Yap_BigIntOfTerm(t1), Yap_BigIntOfTerm(t2)); - RBIG(&new); - } + /* I know the term is much larger, so: */ + return Yap_gmq_rdiv_int_big(IntegerOfTerm(t1), t2); +#endif + default: + RERROR(); + } + break; +#ifdef USE_GMP + case (CELL)big_int_e: + switch (ETypeOfTerm(t2)) { + case long_int_e: + /* I know the term is much larger, so: */ + return Yap_gmq_rdiv_big_int(t1, IntegerOfTerm(t2)); + case (CELL)big_int_e: + return Yap_gmq_rdiv_big_big(t1, t2); case double_e: return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); default: @@ -228,11 +231,7 @@ p_fdiv(Term t1, Term t2) } case (CELL)big_int_e: #ifdef USE_GMP - { - Int i1 = IntegerOfTerm(t1); - Float f2 = mpz_get_d(Yap_BigIntOfTerm(t2)); - RFLOAT(((Float)i1/f2)); - } + return Yap_gmp_fdiv_int_big(IntegerOfTerm(t1), t2); #endif default: RERROR(); @@ -253,9 +252,7 @@ p_fdiv(Term t1, Term t2) } case big_int_e: #ifdef USE_GMP - { - RFLOAT(FloatOfTerm(t1)/mpz_get_d(Yap_BigIntOfTerm(t2))); - } + return Yap_gmp_fdiv_float_big(FloatOfTerm(t1), t2); #endif default: RERROR(); @@ -265,19 +262,12 @@ p_fdiv(Term t1, Term t2) #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - { - Int i = IntegerOfTerm(t2); - RFLOAT(mpz_get_d(Yap_BigIntOfTerm(t1))/(Float)i); - } + return Yap_gmp_fdiv_big_int(t1, IntegerOfTerm(t2)); case big_int_e: /* two bignums*/ - RFLOAT(fdiv_bigint(Yap_BigIntOfTerm(t1),Yap_BigIntOfTerm(t2))); - // RFLOAT(mpz_get_d(Yap_BigIntOfTerm(t1))/mpz_get_d(Yap_BigIntOfTerm(t2))); + return Yap_gmp_fdiv_big_big(t1, t2); case double_e: - { - Float dbl = FloatOfTerm(t2); - RFLOAT(mpz_get_d(Yap_BigIntOfTerm(t1))/dbl); - } + return Yap_gmp_fdiv_big_float(t1, FloatOfTerm(t2)); default: RERROR(); } @@ -288,27 +278,6 @@ p_fdiv(Term t1, Term t2) RERROR(); } -#if USE_GMP -#if !defined(HAVE_MPZ_XOR) -static void -mpz_xor(MP_INT *new, MP_INT *r1, MP_INT *r2) -{ - MP_INT *n2, *n3; - - mpz_new(n2); - mpz_new(n3); - mpz_ior(new, r1, r2); - mpz_com(n2, r1); - mpz_and(n2, n2, new); - mpz_com(n3, r2); - mpz_and(n3, n3, new); - mpz_ior(new, n2, n3); - mpz_clear(n2); - mpz_clear(n3); -} -#endif -#endif - /* xor # */ @@ -326,13 +295,7 @@ p_xor(Term t1, Term t2) return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "#/2"); case big_int_e: #ifdef USE_GMP - { - MP_INT new; - - mpz_init_set_si(&new,IntegerOfTerm(t1)); - mpz_xor(&new, &new, Yap_BigIntOfTerm(t2)); - RBIG(&new); - } + return Yap_gmp_xor_int_big(IntegerOfTerm(t1), t2); #endif default: RERROR(); @@ -344,22 +307,9 @@ p_xor(Term t1, Term t2) #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - { - MP_INT new; - - mpz_init_set_si(&new,IntegerOfTerm(t2)); - mpz_xor(&new, Yap_BigIntOfTerm(t1), &new); - RBIG(&new); - } + return Yap_gmp_xor_int_big(IntegerOfTerm(t2), t1); case big_int_e: - /* two bignums */ - { - MP_INT new; - - mpz_init_set(&new, Yap_BigIntOfTerm(t1)); - mpz_xor(&new, &new, Yap_BigIntOfTerm(t2)); - RBIG(&new); - } + return Yap_gmp_xor_big_big(t1, t2); case double_e: return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "#/2"); default: @@ -390,7 +340,7 @@ p_atan2(Term t1, Term t2) #ifdef USE_GMP { Int i1 = IntegerOfTerm(t1); - Float f2 = mpz_get_d(Yap_BigIntOfTerm(t2)); + Float f2 = Yap_gmp_to_float(t2); RFLOAT(atan2(i1,f2)); } #endif @@ -414,7 +364,7 @@ p_atan2(Term t1, Term t2) case big_int_e: #ifdef USE_GMP { - RFLOAT(atan2(FloatOfTerm(t1),mpz_get_d(Yap_BigIntOfTerm(t2)))); + RFLOAT(atan2(FloatOfTerm(t1),Yap_gmp_to_float(t2))); } #endif default: @@ -423,22 +373,25 @@ p_atan2(Term t1, Term t2) break; case big_int_e: #ifdef USE_GMP - switch (ETypeOfTerm(t2)) { - case long_int_e: - { - Int i = IntegerOfTerm(t2); - RFLOAT(atan2(mpz_get_d(Yap_BigIntOfTerm(t1)),i)); + { + Float dbl1 = Yap_gmp_to_float(t1); + switch (ETypeOfTerm(t2)) { + case long_int_e: + { + Int i = IntegerOfTerm(t2); + RFLOAT(atan2(dbl1,i)); + } + case big_int_e: + /* two bignums */ + RFLOAT(atan2(dbl1,Yap_gmp_to_float(t2))); + case double_e: + { + Float dbl = FloatOfTerm(t2); + RFLOAT(atan2(dbl1,dbl)); + } + default: + RERROR(); } - case big_int_e: - /* two bignums */ - RFLOAT(atan2(mpz_get_d(Yap_BigIntOfTerm(t1)),mpz_get_d(Yap_BigIntOfTerm(t2)))); - case double_e: - { - Float dbl = FloatOfTerm(t2); - RFLOAT(atan2(mpz_get_d(Yap_BigIntOfTerm(t1)),dbl)); - } - default: - RERROR(); } #endif default: @@ -475,7 +428,7 @@ p_power(Term t1, Term t2) #ifdef USE_GMP { Int i1 = IntegerOfTerm(t1); - Float f2 = mpz_get_d(Yap_BigIntOfTerm(t2)); + Float f2 = Yap_gmp_to_float(t2); RFLOAT(pow(i1,f2)); } #endif @@ -499,7 +452,7 @@ p_power(Term t1, Term t2) case big_int_e: #ifdef USE_GMP { - RFLOAT(pow(FloatOfTerm(t1),mpz_get_d(Yap_BigIntOfTerm(t2)))); + RFLOAT(pow(FloatOfTerm(t1),Yap_gmp_to_float(t2))); } #endif default: @@ -512,15 +465,15 @@ p_power(Term t1, Term t2) case long_int_e: { Int i = IntegerOfTerm(t2); - RFLOAT(pow(mpz_get_d(Yap_BigIntOfTerm(t1)),i)); + RFLOAT(pow(Yap_gmp_to_float(t1),i)); } case big_int_e: /* two bignums */ - RFLOAT(pow(mpz_get_d(Yap_BigIntOfTerm(t1)),mpz_get_d(Yap_BigIntOfTerm(t2)))); + RFLOAT(pow(Yap_gmp_to_float(t1),Yap_gmp_to_float(t2))); case double_e: { Float dbl = FloatOfTerm(t2); - RFLOAT(pow(mpz_get_d(Yap_BigIntOfTerm(t1)),dbl)); + RFLOAT(pow(Yap_gmp_to_float(t1),dbl)); } default: RERROR(); @@ -587,7 +540,7 @@ p_exp(Term t1, Term t2) /* two integers */ if ((i1 && !pow)) { /* overflow */ - return Yap_gmp_exp_ints(i1, i2); + return Yap_gmp_exp_int_int(i1, i2); } #endif RINT(pow); @@ -602,7 +555,8 @@ p_exp(Term t1, Term t2) case big_int_e: #ifdef USE_GMP { - return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, "^/2"); + Int i = IntegerOfTerm(t1); + return Yap_gmp_exp_int_big(i,t2); } #endif default: @@ -625,7 +579,7 @@ p_exp(Term t1, Term t2) case big_int_e: #ifdef USE_GMP { - return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, "^/2"); + RFLOAT(pow(FloatOfTerm(t1),Yap_gmp_to_float(t2))); } #endif default: @@ -638,16 +592,15 @@ p_exp(Term t1, Term t2) case long_int_e: { Int i = IntegerOfTerm(t2); - return Yap_gmp_exp_big_int(Yap_BigIntOfTerm(t1),i); + return Yap_gmp_exp_big_int(t1,i); } case big_int_e: /* two bignums, makes no sense */ - // - return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t1, "^/2"); + return Yap_gmp_exp_big_big(t1,t2); case double_e: { Float dbl = FloatOfTerm(t2); - RFLOAT(pow(mpz_get_d(Yap_BigIntOfTerm(t1)),dbl)); + RFLOAT(pow(Yap_gmp_to_float(t1),dbl)); } default: RERROR(); @@ -728,18 +681,7 @@ p_gcd(Term t1, Term t2) return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "gcd/2"); case big_int_e: #ifdef USE_GMP - /* I know the term is much larger, so: */ - { - Int i = IntegerOfTerm(t1); - - if (i > 0) { - RINT(mpz_gcd_ui(NULL,Yap_BigIntOfTerm(t2),i)); - } else if (i == 0) { - RINT(0); - } else { - RINT(mpz_gcd_ui(NULL,Yap_BigIntOfTerm(t2),-i)); - } - } + return Yap_gmp_gcd_int_big(IntegerOfTerm(t1), t2); #endif default: RERROR(); @@ -751,27 +693,9 @@ p_gcd(Term t1, Term t2) #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - /* modulo between bignum and integer */ - { - Int i = IntegerOfTerm(t2); - - if (i > 0) { - RINT(mpz_gcd_ui(NULL,Yap_BigIntOfTerm(t1),i)); - } else if (i == 0) { - RINT(0); - } else { - RINT(mpz_gcd_ui(NULL,Yap_BigIntOfTerm(t1),-i)); - } - } + return Yap_gmp_gcd_int_big(IntegerOfTerm(t2), t1); case big_int_e: - /* two bignums */ - { - MP_INT new; - - mpz_init_set(&new, Yap_BigIntOfTerm(t1)); - mpz_gcd(&new, &new, Yap_BigIntOfTerm(t2)); - RBIG(&new); - } + return Yap_gmp_gcd_big_big(t1, t2); case double_e: return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "gcd/2"); default: @@ -811,15 +735,10 @@ p_min(Term t1, Term t2) } case big_int_e: #ifdef USE_GMP - { - Int i = IntegerOfTerm(t1); - MP_INT *b = Yap_BigIntOfTerm(t2); - - if (mpz_cmp_si(b,i) < 0) { - return t2; - } + if (Yap_gmp_cmp_int_big(IntegerOfTerm(t1), t2) < 0) { return t1; } + return t2; #endif default: RERROR(); @@ -848,15 +767,10 @@ p_min(Term t1, Term t2) } case big_int_e: #ifdef USE_GMP - { - Float fl1 = FloatOfTerm(t1); - Float fl2 = mpz_get_d(Yap_BigIntOfTerm(t2)); - if (fl1 <= fl2) { - return t1; - } else { - return t2; - } + if (Yap_gmp_cmp_float_big(FloatOfTerm(t1), t2) < 0) { + return t1; } + return t2; #endif default: RERROR(); @@ -866,37 +780,20 @@ p_min(Term t1, Term t2) #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - { - Int i = IntegerOfTerm(t2); - MP_INT *b = Yap_BigIntOfTerm(t1); - - if (mpz_cmp_si(b,i) < 0) { - return t1; - } - return t2; + if (Yap_gmp_cmp_big_int(t1, IntegerOfTerm(t2)) < 0) { + return t1; } + return t2; case big_int_e: - /* two bignums */ - { - MP_INT *b1 = Yap_BigIntOfTerm(t1); - MP_INT *b2 = Yap_BigIntOfTerm(t2); - - if (mpz_cmp(b1,b2) < 0) { - return t1; - } else { - return t2; - } + if (Yap_gmp_cmp_big_big(t1, t2) < 0) { + return t1; } + return t2; case double_e: - { - Float fl1 = FloatOfTerm(t2); - Float fl2 = mpz_get_d(Yap_BigIntOfTerm(t1)); - if (fl1 <= fl2) { - return t2; - } else { - return t1; - } + if (Yap_gmp_cmp_big_float(t1, FloatOfTerm(t2)) < 0) { + return t1; } + return t2; default: RERROR(); } @@ -934,15 +831,10 @@ p_max(Term t1, Term t2) } case big_int_e: #ifdef USE_GMP - { - Int i = IntegerOfTerm(t1); - MP_INT *b = Yap_BigIntOfTerm(t2); - - if (mpz_cmp_si(b,i) > 0) { - return t2; - } + if (Yap_gmp_cmp_int_big(IntegerOfTerm(t1), t2) > 0) { return t1; } + return t2; #endif default: RERROR(); @@ -971,15 +863,10 @@ p_max(Term t1, Term t2) } case big_int_e: #ifdef USE_GMP - { - Float fl1 = FloatOfTerm(t1); - Float fl2 = mpz_get_d(Yap_BigIntOfTerm(t2)); - if (fl1 >= fl2) { - return t1; - } else { - return t2; - } + if (Yap_gmp_cmp_float_big(FloatOfTerm(t1), t2) > 0) { + return t1; } + return t2; #endif default: RERROR(); @@ -989,37 +876,20 @@ p_max(Term t1, Term t2) #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - { - Int i = IntegerOfTerm(t2); - MP_INT *b = Yap_BigIntOfTerm(t1); - - if (mpz_cmp_si(b,i) > 0) { - return t1; - } - return t2; + if (Yap_gmp_cmp_big_int(t1, IntegerOfTerm(t2)) > 0) { + return t1; } + return t2; case big_int_e: - /* two bignums */ - { - MP_INT *b1 = Yap_BigIntOfTerm(t1); - MP_INT *b2 = Yap_BigIntOfTerm(t2); - - if (mpz_cmp(b1,b2) > 0) { - return t1; - } else { - return t2; - } + if (Yap_gmp_cmp_big_big(t1, t2) > 0) { + return t1; } + return t2; case double_e: - { - Float fl1 = FloatOfTerm(t2); - Float fl2 = mpz_get_d(Yap_BigIntOfTerm(t1)); - if (fl1 >= fl2) { - return t2; - } else { - return t1; - } + if (Yap_gmp_cmp_big_float(t1, FloatOfTerm(t2)) > 0) { + return t1; } + return t2; default: RERROR(); } @@ -1070,6 +940,8 @@ eval2(Int fi, Term t1, Term t2) { return p_min(t1, t2); case op_max: return p_max(t1, t2); + case op_rdiv: + return p_rdiv(t1, t2); } RERROR(); } @@ -1103,7 +975,8 @@ static InitBinEntry InitBinTab[] = { {"exp", op_power2}, {"gcd", op_gcd}, {"min", op_min}, - {"max", op_max} + {"max", op_max}, + {"rdiv", op_rdiv} }; static Int diff --git a/C/bignum.c b/C/bignum.c index a6ff9a6bd..1b65e23db 100755 --- a/C/bignum.c +++ b/C/bignum.c @@ -66,6 +66,54 @@ Yap_BigIntOfTerm(Term t) return(new); } +Term +Yap_MkBigRatTerm(MP_RAT *big) +{ + Int nlimbs; + MP_INT *dst = (MP_INT *)(H+2); + MP_INT *num = mpq_numref(big); + MP_INT *den = mpq_denref(big); + MP_RAT *rat; + CELL *ret = H; + + if (mpz_cmp_si(den, 1) == 0) + return Yap_MkBigIntTerm(num); + if ((num->_mp_alloc+den->_mp_alloc)*(sizeof(mp_limb_t)/CellSize) > (ASP-ret)-1024) { + return TermNil; + } + H[0] = (CELL)FunctorBigInt; + H[1] = BIG_RATIONAL; + dst->_mp_alloc = 0; + rat = (MP_RAT *)(dst+1); + rat->_mp_num._mp_size = num->_mp_size; + rat->_mp_num._mp_alloc = num->_mp_alloc; + nlimbs = (num->_mp_alloc)*(sizeof(mp_limb_t)/CellSize); + memmove((void *)(rat+1), (const void *)(num->_mp_d), nlimbs*CellSize); + rat->_mp_den._mp_size = den->_mp_size; + rat->_mp_den._mp_alloc = den->_mp_alloc; + H = (CELL *)(rat+1)+nlimbs; + nlimbs = (den->_mp_alloc)*(sizeof(mp_limb_t)/CellSize); + memmove((void *)(H), (const void *)(den->_mp_d), nlimbs*CellSize); + H += nlimbs; + dst->_mp_size = (H-(CELL *)rat); + H[0] = EndSpecials; + H++; + return AbsAppl(ret); +} + +MP_RAT * +Yap_BigRatOfTerm(Term t) +{ + MP_RAT *new = (MP_RAT *)(RepAppl(t)+2+sizeof(MP_INT)/sizeof(CELL)); + mp_limb_t *nt; + + nt = new->_mp_num._mp_d = (mp_limb_t *)(new+1); + nt += new->_mp_num._mp_alloc; + new->_mp_den._mp_d = nt; + return new; +} + + #endif Term diff --git a/C/gmp_support.c b/C/gmp_support.c index ff0ef079f..c0704e0e0 100755 --- a/C/gmp_support.c +++ b/C/gmp_support.c @@ -33,6 +33,17 @@ MkBigAndClose(MP_INT *new) return t; } +static inline Term +MkRatAndClose(MP_RAT *new) +{ + Term t = Yap_MkBigRatTerm(new); + mpq_clear(new); + if (t == TermNil) { + return Yap_ArithError(RESOURCE_ERROR_STACK, t, ">>/2"); + } + return t; +} + /* add i + j using temporary bigint new */ Term Yap_gmp_add_ints(Int i, Int j) @@ -98,244 +109,741 @@ Yap_gmp_sll_ints(Int i, Int j) /* add i + b using temporary bigint new */ Term -Yap_gmp_add_int_big(Int i, MP_INT *b) +Yap_gmp_add_int_big(Int i, Term t) { - MP_INT new; - - mpz_init_set_si(&new, i); - mpz_add(&new, &new, b); - return MkBigAndClose(&new); + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT new; + MP_INT *b = Yap_BigIntOfTerm(t); + mpz_init_set_si(&new, i); + mpz_add(&new, &new, b); + return MkBigAndClose(&new); + } else { + MP_RAT new; + MP_RAT *b = Yap_BigRatOfTerm(t); + mpq_init(&new); + mpq_set_si(&new, i, 1L); + mpq_add(&new, &new, b); + return MkRatAndClose(&new); + } } /* sub i - b using temporary bigint new */ Term -Yap_gmp_sub_int_big(Int i, MP_INT *b) +Yap_gmp_sub_int_big(Int i, Term t) { - MP_INT new; + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT new; + MP_INT *b = Yap_BigIntOfTerm(t); - mpz_init_set_si(&new, i); - mpz_sub(&new, &new, b); - return MkBigAndClose(&new); + mpz_init_set_si(&new, i); + mpz_sub(&new, &new, b); + return MkBigAndClose(&new); + } else { + MP_RAT new; + MP_RAT *b = Yap_BigRatOfTerm(t); + + mpq_init(&new); + mpq_set_si(&new, i, 1L); + mpq_sub(&new, &new, b); + return MkRatAndClose(&new); + } } /* add i + b using temporary bigint new */ Term -Yap_gmp_mul_int_big(Int i, MP_INT *b) +Yap_gmp_mul_int_big(Int i, Term t) { - MP_INT new; + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT new; + MP_INT *b = Yap_BigIntOfTerm(t); - mpz_init_set_si(&new, i); - mpz_mul(&new, &new, b); - return MkBigAndClose(&new); + mpz_init_set_si(&new, i); + mpz_mul(&new, &new, b); + return MkBigAndClose(&new); + } else { + MP_RAT new; + MP_RAT *b = Yap_BigRatOfTerm(t); + + mpq_init(&new); + mpq_set_si(&new, i, 1L); + mpq_mul(&new, &new, b); + return MkRatAndClose(&new); + } } /* sub i - b using temporary bigint new */ Term -Yap_gmp_sub_big_int(MP_INT *b, Int i) +Yap_gmp_sub_big_int(Term t, Int i) { - MP_INT new; + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT new; + MP_INT *b = Yap_BigIntOfTerm(t); - mpz_init_set_si(&new, i); - mpz_neg(&new, &new); - mpz_add(&new, &new, b); - return MkBigAndClose(&new); + mpz_init_set_si(&new, i); + mpz_neg(&new, &new); + mpz_add(&new, &new, b); + return MkBigAndClose(&new); + } else { + MP_RAT new; + MP_RAT *b = Yap_BigRatOfTerm(t); + + mpq_init(&new); + mpq_set_si(&new, i, 1L); + mpq_sub(&new, b, &new); + return MkRatAndClose(&new); + } } /* div i / b using temporary bigint new */ Term -Yap_gmp_div_big_int(MP_INT *b, Int i) +Yap_gmp_div_int_big(Int i, Term t) { - MP_INT new; - - mpz_init_set(&new, b); - if (yap_flags[INTEGER_ROUNDING_FLAG] == 0) { - if (i > 0) { - mpz_tdiv_q_ui(&new, &new, i); - } else if (i == 0) { - return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, MkIntTerm(0), "// /2"); - } else { - /* we do not handle MIN_INT */ - mpz_tdiv_q_ui(&new, &new, -i); - mpz_neg(&new, &new); - } + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + /* cool */ + return MkIntTerm(0); } else { - if (i > 0) { - mpz_fdiv_q_ui(&new, &new, i); - } else if (i == 0) { - return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, MkIntTerm(0), "// /2"); - } else { - /* we do not handle MIN_INT */ - mpz_fdiv_q_ui(&new, &new, -i); - mpz_neg(&new, &new); - } + MP_RAT new; + MP_RAT *b = Yap_BigRatOfTerm(t); + + mpq_init(&new); + mpq_set_si(&new, i, 1L); + mpq_div(&new, &new, b); + return MkRatAndClose(&new); } - return MkBigAndClose(&new); } -/* sub i - b using temporary bigint new */ +/* div i / b using temporary bigint new */ Term -Yap_gmp_and_int_big(Int i, MP_INT *b) +Yap_gmp_div_big_int(Term t, Int i) +{ + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT new; + MP_INT *b = Yap_BigIntOfTerm(t); + + mpz_init_set(&new, b); + if (yap_flags[INTEGER_ROUNDING_FLAG] == 0) { + if (i > 0) { + mpz_tdiv_q_ui(&new, &new, i); + } else if (i == 0) { + return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, MkIntTerm(0), "// /2"); + } else { + /* we do not handle MIN_INT */ + mpz_tdiv_q_ui(&new, &new, -i); + mpz_neg(&new, &new); + } + } else { + if (i > 0) { + mpz_fdiv_q_ui(&new, &new, i); + } else if (i == 0) { + return Yap_ArithError(EVALUATION_ERROR_ZERO_DIVISOR, MkIntTerm(0), "// /2"); + } else { + /* we do not handle MIN_INT */ + mpz_fdiv_q_ui(&new, &new, -i); + mpz_neg(&new, &new); + } + } + return MkBigAndClose(&new); + } else { + MP_RAT new; + MP_RAT *b = Yap_BigRatOfTerm(t); + + mpq_init(&new); + mpq_set_si(&new, i, 1L); + mpq_div(&new, b, &new); + return MkRatAndClose(&new); + } +} + +/* and i - b using temporary bigint new */ +Term +Yap_gmp_and_int_big(Int i, Term t) { MP_INT new; + CELL *pt = RepAppl(t); + MP_INT *b; + if (pt[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "/\\/2"); + } + b = Yap_BigIntOfTerm(t); mpz_init_set_si(&new, i); mpz_and(&new, &new, b); return MkBigAndClose(&new); } -/* sub i - b using temporary bigint new */ +/* or i - b using temporary bigint new */ Term -Yap_gmp_ior_int_big(Int i, MP_INT *b) +Yap_gmp_ior_int_big(Int i, Term t) { MP_INT new; + CELL *pt = RepAppl(t); + MP_INT *b; + if (pt[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "\\/ /2"); + } + b = Yap_BigIntOfTerm(t); mpz_init_set_si(&new, i); mpz_ior(&new, &new, b); return MkBigAndClose(&new); } -/* add i + b using temporary bigint new */ +#if USE_GMP +#if !defined(HAVE_MPZ_XOR) +static void +mpz_xor(MP_INT *new, MP_INT *r1, MP_INT *r2) +{ + MP_INT *n2, *n3; + + mpz_new(n2); + mpz_new(n3); + mpz_ior(new, r1, r2); + mpz_com(n2, r1); + mpz_and(n2, n2, new); + mpz_com(n3, r2); + mpz_and(n3, n3, new); + mpz_ior(new, n2, n3); + mpz_clear(n2); + mpz_clear(n3); +} +#endif +#endif + +/* or i - b using temporary bigint new */ Term -Yap_gmp_sll_big_int(MP_INT *b, Int i) +Yap_gmp_xor_int_big(Int i, Term t) { MP_INT new; - - if (i > 0) { - mpz_init_set(&new, b); - mpz_mul_2exp(&new, &new, i); - } else if (i == 0) { - mpz_init_set(&new, b); - } else { - mpz_init_set(&new, b); - if (i == Int_MIN) { - return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, MkIntegerTerm(i), "< 0) { + mpz_init_set(&new, b); + mpz_mul_2exp(&new, &new, i); + } else if (i == 0) { + return t; + } else { + mpz_init_set(&new, b); + if (i == Int_MIN) { + return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, MkIntegerTerm(i), "< 0) { + mpq_init(&new); + mpq_mul_2exp (&new, b, i); + } else if (i == 0) { + return t; + } else { + mpq_init(&new); + mpq_div_2exp (&new, b, i); + } + return MkRatAndClose(&new); + } } Term -Yap_gmp_sub_big_big(MP_INT *b1, MP_INT *b2) +Yap_gmp_add_big_big(Term t1, Term t2) { - MP_INT new; + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); - mpz_init_set(&new, b1); - mpz_sub(&new, &new, b2); - return MkBigAndClose(&new); + mpz_init_set(&new, b1); + mpz_add(&new, &new, b2); + return MkBigAndClose(&new); + } else { + MP_RAT new; + MP_RAT *b1, bb1; + MP_RAT *b2, bb2; + if (pt1[1] == BIG_INT) { + b1 = &bb1; + mpq_init(b1); + mpq_set_z(b1, Yap_BigIntOfTerm(t1)); + } else { + b1 = Yap_BigRatOfTerm(t1); + } + if (pt2[1] == BIG_INT) { + b2 = &bb2; + mpq_init(b2); + mpq_set_z(b2, Yap_BigIntOfTerm(t2)); + } else { + b2 = Yap_BigRatOfTerm(t2); + } + mpq_init(&new); + mpq_add(&new, b1, b2); + return MkRatAndClose(&new); + } } Term -Yap_gmp_mul_big_big(MP_INT *b1, MP_INT *b2) +Yap_gmp_sub_big_big(Term t1, Term t2) { - MP_INT new; + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); - mpz_init_set(&new, b1); - mpz_mul(&new, &new, b2); - return MkBigAndClose(&new); + mpz_init_set(&new, b1); + mpz_sub(&new, &new, b2); + return MkBigAndClose(&new); + } else { + MP_RAT new; + MP_RAT *b1, bb1; + MP_RAT *b2, bb2; + if (pt1[1] == BIG_INT) { + b1 = &bb1; + mpq_init(b1); + mpq_set_z(b1, Yap_BigIntOfTerm(t1)); + } else { + b1 = Yap_BigRatOfTerm(t1); + } + if (pt2[1] == BIG_INT) { + b2 = &bb2; + mpq_init(b2); + mpq_set_z(b2, Yap_BigIntOfTerm(t2)); + } else { + b2 = Yap_BigRatOfTerm(t2); + } + mpq_init(&new); + mpq_sub(&new, b1, b2); + return MkRatAndClose(&new); + } +} + +Term +Yap_gmp_mul_big_big(Term t1, Term t2) +{ + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); + + mpz_init_set(&new, b1); + mpz_mul(&new, &new, b2); + return MkBigAndClose(&new); + } else { + MP_RAT new; + MP_RAT *b1, bb1; + MP_RAT *b2, bb2; + if (pt1[1] == BIG_INT) { + b1 = &bb1; + mpq_init(b1); + mpq_set_z(b1, Yap_BigIntOfTerm(t1)); + } else { + b1 = Yap_BigRatOfTerm(t1); + } + if (pt2[1] == BIG_INT) { + b2 = &bb2; + mpq_init(b2); + mpq_set_z(b2, Yap_BigIntOfTerm(t2)); + } else { + b2 = Yap_BigRatOfTerm(t2); + } + mpq_init(&new); + mpq_mul(&new, b1, b2); + return MkRatAndClose(&new); + } } /* div i / b using temporary bigint new */ Term -Yap_gmp_div_big_big(MP_INT *b1, MP_INT *b2) +Yap_gmp_div_big_big(Term t1, Term t2) { - MP_INT new; + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); - mpz_init_set(&new, b1); - if (yap_flags[INTEGER_ROUNDING_FLAG] == 0) { - mpz_tdiv_q(&new, &new, b2); + mpz_init_set(&new, b1); + if (yap_flags[INTEGER_ROUNDING_FLAG] == 0) { + mpz_tdiv_q(&new, &new, b2); + } else { + mpz_fdiv_q(&new, &new, b2); + } + return MkBigAndClose(&new); } else { - mpz_fdiv_q(&new, &new, b2); + MP_RAT new; + MP_RAT *b1, bb1; + MP_RAT *b2, bb2; + if (pt1[1] == BIG_INT) { + b1 = &bb1; + mpq_init(b1); + mpq_set_z(b1, Yap_BigIntOfTerm(t1)); + } else { + b1 = Yap_BigRatOfTerm(t1); + } + if (pt2[1] == BIG_INT) { + b2 = &bb2; + mpq_init(b2); + mpq_set_z(b2, Yap_BigIntOfTerm(t2)); + } else { + b2 = Yap_BigRatOfTerm(t2); + } + mpq_init(&new); + mpq_div(&new, b1, b2); + return MkRatAndClose(&new); } - return MkBigAndClose(&new); } Term -Yap_gmp_and_big_big(MP_INT *b1, MP_INT *b2) +Yap_gmp_and_big_big(Term t1, Term t2) { - MP_INT new; + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); - mpz_init_set(&new, b1); - mpz_and(&new, &new, b2); - return MkBigAndClose(&new); + mpz_init_set(&new, b1); + mpz_and(&new, &new, b2); + return MkBigAndClose(&new); + } else { + if (pt1[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "/\\/2"); + } + return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "/\\/2"); + } } Term -Yap_gmp_ior_big_big(MP_INT *b1, MP_INT *b2) +Yap_gmp_ior_big_big(Term t1, Term t2) { - MP_INT new; + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); - mpz_init_set(&new, b1); - mpz_ior(&new, &new, b2); - return MkBigAndClose(&new); + mpz_init_set(&new, b1); + mpz_ior(&new, &new, b2); + return MkBigAndClose(&new); + } else { + if (pt1[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "\\/ /2"); + } + return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "\\/ /2"); + } } Term -Yap_gmp_mod_big_big(MP_INT *b1, MP_INT *b2) +Yap_gmp_xor_big_big(Term t1, Term t2) { - MP_INT new; + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); - mpz_init(&new); - mpz_fdiv_r(&new, b1, b2); - return MkBigAndClose(&new); + mpz_init_set(&new, b1); + mpz_xor(&new, &new, b2); + return MkBigAndClose(&new); + } else { + if (pt1[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "\\/ /2"); + } + return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "\\/ /2"); + } } Term -Yap_gmp_mod_big_int(MP_INT *b, Int i2) +Yap_gmp_mod_big_big(Term t1, Term t2) { - MP_INT new; + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); - mpz_init_set_si(&new, i2); - mpz_fdiv_r(&new, b, &new); - return MkBigAndClose(&new); + mpz_init(&new); + mpz_fdiv_r(&new, b1, b2); + return MkBigAndClose(&new); + } else { + if (pt1[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "mod/2"); + } + return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "mod/2"); + } } Term -Yap_gmp_mod_int_big(Int i1, MP_INT *b) +Yap_gmp_mod_big_int(Term t, Int i2) { - MP_INT new; + CELL *pt = RepAppl(t); + if (pt[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "mod/2"); + } else { + MP_INT *b = Yap_BigIntOfTerm(t); + MP_INT new; - mpz_init_set_si(&new, i1); - mpz_fdiv_r(&new, &new, b); - RBIG(&new); + mpz_init_set_si(&new, i2); + mpz_fdiv_r(&new, b, &new); + return MkBigAndClose(&new); + } +} + +Term +Yap_gmp_mod_int_big(Int i1, Term t) +{ + CELL *pt = RepAppl(t); + if (pt[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "mod/2"); + } else { + MP_INT *b = Yap_BigIntOfTerm(t); + /* integer is much smaller */ + + if (mpz_sgn(b) > 0) { + /* easy case next */ + if (i1 > 0) { + /* 2 mod 23 -> 2 */ + return MkIntegerTerm(i1); + } else { + MP_INT new; + + /* 2 mod -23 -> 21 */ + mpz_init_set_si(&new, i1); + mpz_add(&new, &new, b); + return MkBigAndClose(&new); + } + } else { + if (i1 > 0) { + MP_INT new; + + /* -2 mod 23 -> 21 */ + mpz_init_set_si(&new, i1); + mpz_add(&new, b, &new); + return MkBigAndClose(&new); + } else { + /* -2 mod -23 -> -2 */ + return MkIntegerTerm(i1); + } + } + } +} + +Term +Yap_gmp_rem_big_big(Term t1, Term t2) +{ + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); + + mpz_init(&new); + mpz_tdiv_r(&new, b1, b2); + return MkBigAndClose(&new); + } else { + if (pt1[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "rem/2"); + } + return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "rem/2"); + } +} + +Term +Yap_gmp_rem_big_int(Term t, Int i2) +{ + CELL *pt = RepAppl(t); + if (pt[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "mod/2"); + } else { + MP_INT *b = Yap_BigIntOfTerm(t); + MP_INT new; + + mpz_init_set_si(&new, i2); + mpz_tdiv_r(&new, b, &new); + return MkBigAndClose(&new); + } +} + +Term +Yap_gmp_rem_int_big(Int i1, Term t) +{ + CELL *pt = RepAppl(t); + if (pt[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "mod/2"); + } else { + /* integer is much smaller */ + return MkIntegerTerm(i1); + } +} + +Term +Yap_gmp_gcd_big_big(Term t1, Term t2) +{ + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT new; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); + + mpz_init_set(&new, b1); + mpz_gcd(&new, &new, b2); + return MkBigAndClose(&new); + } else { + if (pt1[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t1, "gcd/2"); + } + return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "gcd/2"); + } +} + +Term +Yap_gmp_gcd_int_big(Int i, Term t) +{ + CELL *pt = RepAppl(t); + if (pt[1] != BIG_INT) { + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "mod/2"); + } else { + /* integer is much smaller */ + if (i > 0) { + return MkIntegerTerm(mpz_gcd_ui(NULL,Yap_BigIntOfTerm(t),i)); + } else if (i == 0) { + return MkIntTerm(0); + } else { + return MkIntegerTerm(mpz_gcd_ui(NULL,Yap_BigIntOfTerm(t),-i)); + } + } +} + +Float +Yap_gmp_to_float(Term t) +{ + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return mpz_get_d(b); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + return mpq_get_d(b); + } } Term -Yap_gmp_add_float_big(Float d, MP_INT *b) +Yap_gmp_add_float_big(Float d, Term t) { - return MkFloatTerm(d+mpz_get_d(b)); + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return MkFloatTerm(d+mpz_get_d(b)); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + return MkFloatTerm(d+mpq_get_d(b)); + } } Term -Yap_gmp_sub_float_big(Float d, MP_INT *b) +Yap_gmp_sub_float_big(Float d, Term t) { - return MkFloatTerm(d-mpz_get_d(b)); + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return MkFloatTerm(d-mpz_get_d(b)); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + return MkFloatTerm(d-mpq_get_d(b)); + } } Term -Yap_gmp_sub_big_float(MP_INT *b, Float d) +Yap_gmp_sub_big_float(Term t, Float d) { - return MkFloatTerm(mpz_get_d(b)-d); + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return MkFloatTerm(mpz_get_d(b)-d); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + return MkFloatTerm(mpq_get_d(b)-d); + } } Term -Yap_gmp_mul_float_big(Float d, MP_INT *b) +Yap_gmp_mul_float_big(Float d, Term t) { - return MkFloatTerm(d*mpz_get_d(b)); + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return MkFloatTerm(d*mpz_get_d(b)); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + return MkFloatTerm(d*mpq_get_d(b)); + } } Term -Yap_gmp_exp_ints(Int i1, Int i2) +Yap_gmp_fdiv_float_big(Float d, Term t) +{ + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return MkFloatTerm(d/mpz_get_d(b)); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + return MkFloatTerm(d/mpq_get_d(b)); + } +} + +Term +Yap_gmp_fdiv_big_float(Term t, Float d) +{ + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return MkFloatTerm(mpz_get_d(b)/d); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + return MkFloatTerm(mpq_get_d(b)/d); + } +} + +Term +Yap_gmp_exp_int_int(Int i1, Int i2) { MP_INT new; @@ -345,23 +853,69 @@ Yap_gmp_exp_ints(Int i1, Int i2) } Term -Yap_gmp_exp_big_int(MP_INT *b, Int i) +Yap_gmp_exp_big_int(Term t, Int i) { MP_INT new; - if (b > 0) { - mpz_init(&new); - mpz_pow_ui (&new, b, (unsigned long int)i); - } else { - MP_INT new; - if (b==0) return MkIntTerm(1); + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); - mpz_init_set_si(&new, i); - mpz_powm (&new, b, &new, b); + if (i > 0) { + mpz_init(&new); + mpz_pow_ui (&new, b, (unsigned long int)i); + } else { + MP_INT new; + if (i==0) return MkIntTerm(1); + mpz_init_set_si(&new, i); + mpz_powm (&new, b, &new, b); + } + return MkBigAndClose(&new); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + Float dbl = mpq_get_d(b); + return MkFloatTerm(pow(dbl,i)); } - return MkBigAndClose(&new); } +Term +Yap_gmp_exp_int_big(Int i, Term t) +{ + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t, "^/2"); + } else { + MP_INT *b = Yap_BigIntOfTerm(t); + Float dbl = mpz_get_d(b); + return MkFloatTerm(pow(i,dbl)); + } +} + +Term +Yap_gmp_exp_big_big(Term t1, Term t2) +{ + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + Float dbl1, dbl2; + + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, "^/2"); + } else { + if (pt1[1] != BIG_INT) { + dbl1 = mpz_get_d(Yap_BigIntOfTerm(t1)); + } else { + dbl1 = mpq_get_d(Yap_BigRatOfTerm(t1)); + } + if (pt2[2] != BIG_INT) { + dbl2 = mpz_get_d(Yap_BigIntOfTerm(t2)); + } else { + dbl2 = mpq_get_d(Yap_BigRatOfTerm(t2)); + } + return MkFloatTerm(pow(dbl1,dbl2)); + } +} + + Term Yap_gmp_big_from_64bits(YAP_LONG_LONG i) { @@ -379,6 +933,252 @@ Yap_gmp_big_from_64bits(YAP_LONG_LONG i) return MkBigAndClose(&new); } +Term +Yap_gmq_rdiv_int_int(Int i1, Int i2) +{ + MP_RAT new; + + mpq_init(&new); + mpq_set_si(&new, i1, i2); + mpq_canonicalize(&new); + return MkRatAndClose(&new); +} + +Term +Yap_gmq_rdiv_int_big(Int i1, Term t2) +{ + MP_RAT new, new2; + MP_INT *b = Yap_BigIntOfTerm(t2); + + mpq_init(&new); + mpq_set_si(&new, i1, 1L); + mpq_init(&new2); + mpq_set_z(&new2, b); + mpq_div(&new,&new,&new2); + mpq_clear(&new2); + return MkRatAndClose(&new); +} + +Term +Yap_gmq_rdiv_big_int(Term t1, Int i2) +{ + MP_RAT new, new2; + MP_INT *b = Yap_BigIntOfTerm(t1); + + mpq_init(&new); + mpq_set_si(&new, i2, 1L); + mpq_init(&new2); + mpq_set_z(&new2, b); + mpq_div(&new,&new2,&new); + mpq_clear(&new2); + return MkRatAndClose(&new); +} + +Term +Yap_gmq_rdiv_big_big(Term t1, Term t2) +{ + MP_RAT new, new2; + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); + + mpq_init(&new); + mpq_set_z(&new, b1); + mpq_init(&new2); + mpq_set_z(&new2, b2); + mpq_div(&new,&new,&new2); + mpq_clear(&new2); + return MkRatAndClose(&new); +} + +Term +Yap_gmp_fdiv_int_big(Int i1, Term t2) +{ + MP_RAT new; + MP_RAT *b1, *b2; + MP_RAT bb1, bb2; + Float d; + CELL *pt2 = RepAppl(t2); + + b1 = &bb1; + mpq_init(b1); + mpq_set_si(b1, i1, 1L); + if (pt2[1] == BIG_INT) { + b2 = &bb2; + mpq_init(b2); + mpq_set_z(b2, Yap_BigIntOfTerm(t2)); + } else { + b2 = Yap_BigRatOfTerm(t2); + } + mpq_init(&new); + mpq_div(&new, b1, b2); + d = mpq_get_d(&new); + mpq_clear(&new); + return MkFloatTerm(d); +} + +Term +Yap_gmp_fdiv_big_int(Term t2, Int i1) +{ + MP_RAT new; + MP_RAT *b1, *b2; + MP_RAT bb1, bb2; + Float d; + CELL *pt2 = RepAppl(t2); + + b1 = &bb1; + mpq_init(b1); + mpq_set_si(b1, i1, 1L); + if (pt2[1] == BIG_INT) { + b2 = &bb2; + mpq_init(b2); + mpq_set_z(b2, Yap_BigIntOfTerm(t2)); + } else { + b2 = Yap_BigRatOfTerm(t2); + } + mpq_init(&new); + mpq_div(&new, b2, b1); + d = mpq_get_d(&new); + mpq_clear(&new); + return MkFloatTerm(d); +} + +Term +Yap_gmp_fdiv_big_big(Term t1, Term t2) +{ + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + MP_RAT new; + MP_RAT *b1, bb1; + MP_RAT *b2, bb2; + Float d; + + if (pt1[1] == BIG_INT) { + b1 = &bb1; + mpq_init(b1); + mpq_set_z(b1, Yap_BigIntOfTerm(t1)); + } else { + b1 = Yap_BigRatOfTerm(t1); + } + if (pt2[1] == BIG_INT) { + b2 = &bb2; + mpq_init(b2); + mpq_set_z(b2, Yap_BigIntOfTerm(t2)); + } else { + b2 = Yap_BigRatOfTerm(t2); + } + mpq_init(&new); + mpq_div(&new, b1, b2); + d = mpq_get_d(&new); + mpq_clear(&new); + return MkFloatTerm(d); +} + +int +Yap_gmp_cmp_big_int(Term t, Int i) +{ + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return mpz_cmp_si(b,i); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + return mpq_cmp_si(b,i,1); + } +} + +int +Yap_gmp_cmp_big_float(Term t, Float d) +{ + CELL *pt = RepAppl(t); + if (pt[1] == BIG_INT) { + MP_INT *b = Yap_BigIntOfTerm(t); + return mpz_cmp_d(b,d); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + Float d1 = mpq_get_d(b); + if (d1 < d) + return -1; + if (d1 == d) + return 0; + return 1; + } +} + +int +Yap_gmp_cmp_big_big(Term t1, Term t2) +{ + CELL *pt1 = RepAppl(t1); + CELL *pt2 = RepAppl(t2); + if (pt1[1] == BIG_INT && pt2[1] == BIG_INT) { + MP_INT *b1 = Yap_BigIntOfTerm(t1); + MP_INT *b2 = Yap_BigIntOfTerm(t2); + + return mpz_cmp(b1, b2); + } else { + MP_RAT *b1 = NULL, bb1; + MP_RAT *b2 = NULL, bb2; + if (pt1[1] == BIG_INT) { + b1 = &bb1; + mpq_init(b1); + mpq_set_z(b1, Yap_BigIntOfTerm(t1)); + } else { + b1 = Yap_BigRatOfTerm(t1); + } + if (pt2[1] == BIG_INT) { + b2 = &bb2; + mpq_init(b2); + mpq_set_z(b2, Yap_BigIntOfTerm(t2)); + } else { + b2 = Yap_BigRatOfTerm(t2); + } + return mpq_cmp(b1, b2); + } +} + +Term +Yap_gmp_neg_int(Int i) +{ + MP_INT new; + + mpz_init_set_si(&new, Int_MIN); + mpz_neg(&new, &new); + return MkBigAndClose(&new); +} + +Term +Yap_gmp_neg_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_neg(&new, &new); + return MkBigAndClose(&new); + } else { + MP_RAT *b = Yap_BigRatOfTerm(t); + MP_INT new; + mpq_init(&new); + mpq_neg(&new, b); + return MkRatAndClose(&new); + } +} + +Term +Yap_gmp_unot_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_com(&new, &new); + return MkBigAndClose(&new); + } else { + return Yap_ArithError(TYPE_ERROR_INTEGER, t, "#/1"); + } +} + #endif diff --git a/C/write.c b/C/write.c index 25621bff7..d2f0935d8 100755 --- a/C/write.c +++ b/C/write.c @@ -123,6 +123,116 @@ wrputws(wchar_t *s, wrf writewch) /* writes a string */ wrputc(*s++, writewch); } +#ifdef USE_GMP + +static char * +ensure_space(size_t sz) { + char *s; + + s = (char *) Yap_PreAllocCodeSpace(); + while (s+sz >= (char *)AuxSp) { +#if USE_SYSTEM_MALLOC + /* may require stack expansion */ + if (!Yap_ExpandPreAllocCodeSpace(sz, NULL, TRUE)) { + s = NULL; + break; + } + s = (char *) Yap_PreAllocCodeSpace(); +#else + s = NULL; +#endif + } + if (!s) { + s = (char *)TR; + while (s+sz >= Yap_TrailTop) { + if (!Yap_growtrail(sz/sizeof(CELL), FALSE)) { + s = NULL; + break; + } + s = (char *)TR; + } + } + if (!s) { + s = (char *)H; + if (s+sz >= (char *)ASP) { + Yap_Error(OUT_OF_STACK_ERROR,TermNil,"not enough space to write bignum: it requires %d bytes", sz); + s = NULL; + } + } + return s; +} + +static void +write_mpint(MP_INT *big, wrf writewch) { + char *s; + + s = ensure_space(3+mpz_sizeinbase(big, 10)); + if (mpz_sgn(big) < 0) { + if (lastw == symbol) + wrputc(' ', writewch); + } else { + if (lastw == alphanum) + wrputc(' ', writewch); + } + if (!s) { + s = mpz_get_str(NULL, 10, big); + if (!s) + return; + wrputs(s,writewch); + free(s); + } else { + mpz_get_str(s, 10, big); + wrputs(s,writewch); + } +} + +static void +write_mpq(MP_RAT *q, wrf writewch) { + char *s; + 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); + s = ensure_space(sz); + if (mpq_sgn(q) < 0) { + if (lastw == symbol) + wrputc(' ', writewch); + } else { + if (lastw == alphanum) + wrputc(' ', writewch); + } + if (!s) { + s = mpq_get_str(NULL, 10, q); + if (!s) + return; + wrputs(s,writewch); + free(s); + } else { + mpq_get_str(s, 10, q); + wrputs(s,writewch); + } +} +#endif + +static void +writebig(Term t, wrf writewch) /* writes an integer */ +{ +#ifdef USE_GMP + CELL *pt = RepAppl(t)+1; + if (pt[0] == BIG_INT) + { + MP_INT *big = Yap_BigIntOfTerm(t); + write_mpint(big, writewch); + return; + } else if (pt[0] == BIG_RATIONAL) { + MP_RAT *q = Yap_BigRatOfTerm(t); + write_mpq(q, writewch); + return; + } +#endif + wrputs("0",writewch); +} + static void wrputf(Float f, wrf writewch) /* writes a float */ @@ -630,6 +740,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, str wrputn(LongIntOfTerm(t),wglb->writewch); return; case (CELL)FunctorBigInt: + writebig(t,wglb->writewch); + return; #ifdef USE_GMP { MP_INT *big = Yap_BigIntOfTerm(t); diff --git a/H/TermExt.h b/H/TermExt.h index a7e311c92..47a7d28fc 100644 --- a/H/TermExt.h +++ b/H/TermExt.h @@ -311,6 +311,11 @@ typedef struct { mp_limb_t *_mp_d; } MP_INT; +typedef struct { + MP_INT _mp_num; + MP_INT _mp_den; +} MP_RAT; + #endif inline EXTERN int IsBigIntTerm (Term); @@ -326,6 +331,9 @@ IsBigIntTerm (Term t) Term STD_PROTO (Yap_MkBigIntTerm, (MP_INT *)); MP_INT *STD_PROTO (Yap_BigIntOfTerm, (Term)); +Term STD_PROTO (Yap_MkBigRatTerm, (MP_RAT *)); +MP_RAT *STD_PROTO (Yap_BigRatOfTerm, (Term)); + inline EXTERN void MPZ_SET (mpz_t, MP_INT *); inline EXTERN void diff --git a/H/arith2.h b/H/arith2.h index bfc6cac22..528842106 100644 --- a/H/arith2.h +++ b/H/arith2.h @@ -156,7 +156,7 @@ p_plus(Term t1, Term t2) { } case big_int_e: #ifdef USE_GMP - return(Yap_gmp_add_int_big(IntegerOfTerm(t1), Yap_BigIntOfTerm(t2))); + return(Yap_gmp_add_int_big(IntegerOfTerm(t1), t2)); #endif default: RERROR(); @@ -170,7 +170,7 @@ p_plus(Term t1, Term t2) { RFLOAT(FloatOfTerm(t1)+FloatOfTerm(t2)); case big_int_e: #ifdef USE_GMP - return(Yap_gmp_add_float_big(FloatOfTerm(t1),Yap_BigIntOfTerm(t2))); + return Yap_gmp_add_float_big(FloatOfTerm(t1),t2); #endif default: RERROR(); @@ -179,12 +179,12 @@ p_plus(Term t1, Term t2) { #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - return(Yap_gmp_add_int_big(IntegerOfTerm(t2), Yap_BigIntOfTerm(t1))); + return Yap_gmp_add_int_big(IntegerOfTerm(t2), t1); case big_int_e: /* two bignums */ - return(Yap_gmp_add_big_big(Yap_BigIntOfTerm(t1), Yap_BigIntOfTerm(t2))); + return Yap_gmp_add_big_big(t1, t2); case double_e: - return(Yap_gmp_add_float_big(FloatOfTerm(t2),Yap_BigIntOfTerm(t1))); + return Yap_gmp_add_float_big(FloatOfTerm(t2),t1); default: RERROR(); } @@ -212,7 +212,7 @@ p_minus(Term t1, Term t2) { } case big_int_e: #ifdef USE_GMP - return(Yap_gmp_sub_int_big(IntegerOfTerm(t1), Yap_BigIntOfTerm(t2))); + return Yap_gmp_sub_int_big(IntegerOfTerm(t1), t2); #endif default: RERROR(); @@ -229,7 +229,7 @@ p_minus(Term t1, Term t2) { } case big_int_e: #ifdef USE_GMP - return(Yap_gmp_sub_float_big(FloatOfTerm(t1),Yap_BigIntOfTerm(t2))); + return Yap_gmp_sub_float_big(FloatOfTerm(t1),t2); #endif default: RERROR(); @@ -239,11 +239,11 @@ p_minus(Term t1, Term t2) { #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - return(Yap_gmp_sub_big_int(Yap_BigIntOfTerm(t1), IntegerOfTerm(t2))); + return Yap_gmp_sub_big_int(t1, IntegerOfTerm(t2)); case big_int_e: - return(Yap_gmp_sub_big_big(Yap_BigIntOfTerm(t1), Yap_BigIntOfTerm(t2))); + return Yap_gmp_sub_big_big(t1, t2); case double_e: - return(Yap_gmp_sub_big_float(Yap_BigIntOfTerm(t1),FloatOfTerm(t2))); + return Yap_gmp_sub_big_float(t1,FloatOfTerm(t2)); default: RERROR(); } @@ -272,7 +272,7 @@ p_times(Term t1, Term t2) { } case big_int_e: #ifdef USE_GMP - return(Yap_gmp_mul_int_big(IntegerOfTerm(t1), Yap_BigIntOfTerm(t2))); + return(Yap_gmp_mul_int_big(IntegerOfTerm(t1), t2)); #endif default: RERROR(); @@ -287,7 +287,7 @@ p_times(Term t1, Term t2) { RFLOAT(FloatOfTerm(t1)*FloatOfTerm(t2)); case big_int_e: #ifdef USE_GMP - return(Yap_gmp_mul_float_big(FloatOfTerm(t1),Yap_BigIntOfTerm(t2))); + return Yap_gmp_mul_float_big(FloatOfTerm(t1),t2); #endif default: RERROR(); @@ -297,12 +297,12 @@ p_times(Term t1, Term t2) { #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - return(Yap_gmp_mul_int_big(IntegerOfTerm(t2), Yap_BigIntOfTerm(t1))); + return Yap_gmp_mul_int_big(IntegerOfTerm(t2), t1); case big_int_e: /* two bignums */ - return(Yap_gmp_mul_big_big(Yap_BigIntOfTerm(t1), Yap_BigIntOfTerm(t2))); + return Yap_gmp_mul_big_big(t1, t2); case double_e: - return(Yap_gmp_mul_float_big(FloatOfTerm(t2),Yap_BigIntOfTerm(t1))); + return Yap_gmp_mul_float_big(FloatOfTerm(t2),t1); default: RERROR(); } @@ -340,8 +340,8 @@ p_div(Term t1, Term t2) { return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "// /2"); case big_int_e: #ifdef USE_GMP - /* Cool */ - RINT(0); + /* dividing a bignum by an integer */ + return Yap_gmp_div_int_big(IntegerOfTerm(t1), t2); #endif default: RERROR(); @@ -354,10 +354,10 @@ p_div(Term t1, Term t2) { switch (ETypeOfTerm(t2)) { case long_int_e: /* dividing a bignum by an integer */ - return Yap_gmp_div_big_int(Yap_BigIntOfTerm(t1), IntegerOfTerm(t2)); + return Yap_gmp_div_big_int(t1, IntegerOfTerm(t2)); case big_int_e: /* two bignums */ - return Yap_gmp_div_big_big(Yap_BigIntOfTerm(t1), Yap_BigIntOfTerm(t2)); + return Yap_gmp_div_big_big(t1, t2); case double_e: return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "// /2"); default: @@ -382,7 +382,7 @@ p_and(Term t1, Term t2) { return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "/\\ /2"); case big_int_e: #ifdef USE_GMP - return(Yap_gmp_and_int_big(IntegerOfTerm(t1),Yap_BigIntOfTerm(t2))); + return Yap_gmp_and_int_big(IntegerOfTerm(t1),t2); #endif default: RERROR(); @@ -395,10 +395,10 @@ p_and(Term t1, Term t2) { switch (ETypeOfTerm(t2)) { case long_int_e: /* anding a bignum with an integer is easy */ - return(Yap_gmp_and_int_big(IntegerOfTerm(t2),Yap_BigIntOfTerm(t1))); + return Yap_gmp_and_int_big(IntegerOfTerm(t2),t1); case big_int_e: /* two bignums */ - return(Yap_gmp_and_big_big(Yap_BigIntOfTerm(t2), Yap_BigIntOfTerm(t1))); + return Yap_gmp_and_big_big(t1, t2); case double_e: return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "/\\ /2"); default: @@ -423,7 +423,7 @@ p_or(Term t1, Term t2) { return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "\\/ /2"); case big_int_e: #ifdef USE_GMP - return(Yap_gmp_ior_int_big(IntegerOfTerm(t1),Yap_BigIntOfTerm(t2))); + return Yap_gmp_ior_int_big(IntegerOfTerm(t1),t2); #endif default: RERROR(); @@ -436,10 +436,10 @@ p_or(Term t1, Term t2) { switch (ETypeOfTerm(t2)) { case long_int_e: /* anding a bignum with an integer is easy */ - return(Yap_gmp_ior_int_big(IntegerOfTerm(t2),Yap_BigIntOfTerm(t1))); + return Yap_gmp_ior_int_big(IntegerOfTerm(t2),t1); case big_int_e: /* two bignums */ - return Yap_gmp_ior_big_big(Yap_BigIntOfTerm(t2), Yap_BigIntOfTerm(t1)); + return Yap_gmp_ior_big_big(t1, t2); case double_e: return Yap_ArithError(TYPE_ERROR_INTEGER, t2, "\\/ /2"); default: @@ -483,7 +483,7 @@ p_sll(Term t1, Term t2) { #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - return Yap_gmp_sll_big_int(Yap_BigIntOfTerm(t1), IntegerOfTerm(t2)); + return Yap_gmp_sll_big_int(t1, IntegerOfTerm(t2)); case big_int_e: return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, ">>/2"); case double_e: @@ -529,7 +529,7 @@ p_slr(Term t1, Term t2) { #ifdef USE_GMP switch (ETypeOfTerm(t2)) { case long_int_e: - return Yap_gmp_sll_big_int(Yap_BigIntOfTerm(t1), -IntegerOfTerm(t2)); + return Yap_gmp_sll_big_int(t1, -IntegerOfTerm(t2)); case big_int_e: return Yap_ArithError(RESOURCE_ERROR_HUGE_INT, t2, ">>/2"); case double_e: diff --git a/H/eval.h b/H/eval.h index 8319e2a4e..3ce24a6ac 100644 --- a/H/eval.h +++ b/H/eval.h @@ -121,7 +121,8 @@ typedef enum { /* op_power, */ op_gcd, op_min, - op_max + op_max, + op_rdiv } arith2_op; Functor STD_PROTO(EvalArg,(Term)); @@ -210,43 +211,77 @@ ETypeOfTerm(Term t) return double_e; if (f == FunctorLongInt) return long_int_e; - if (f == FunctorBigInt) + if (f == FunctorBigInt) { return big_int_e; + } } return db_ref_e; } #if USE_GMP +Term STD_PROTO(Yap_gmq_rdiv_int_int,(Int, Int)); +Term STD_PROTO(Yap_gmq_rdiv_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmq_rdiv_big_int,(Term, Int)); +Term STD_PROTO(Yap_gmq_rdiv_big_big,(Term, Term)); + Term STD_PROTO(Yap_gmp_add_ints,(Int, Int)); Term STD_PROTO(Yap_gmp_sub_ints,(Int, Int)); Term STD_PROTO(Yap_gmp_mul_ints,(Int, Int)); Term STD_PROTO(Yap_gmp_sll_ints,(Int, Int)); -Term STD_PROTO(Yap_gmp_add_int_big,(Int, MP_INT *)); -Term STD_PROTO(Yap_gmp_sub_int_big,(Int, MP_INT *)); -Term STD_PROTO(Yap_gmp_sub_big_int,(MP_INT *, Int)); -Term STD_PROTO(Yap_gmp_mul_int_big,(Int, MP_INT *)); -Term STD_PROTO(Yap_gmp_div_big_int,(MP_INT *, Int)); -Term STD_PROTO(Yap_gmp_and_int_big,(Int, MP_INT *)); -Term STD_PROTO(Yap_gmp_ior_int_big,(Int, MP_INT *)); -Term STD_PROTO(Yap_gmp_sll_big_int,(MP_INT *, Int)); -Term STD_PROTO(Yap_gmp_add_big_big,(MP_INT *, MP_INT *)); -Term STD_PROTO(Yap_gmp_sub_big_big,(MP_INT *, MP_INT *)); -Term STD_PROTO(Yap_gmp_mul_big_big,(MP_INT *, MP_INT *)); -Term STD_PROTO(Yap_gmp_div_big_big,(MP_INT *, MP_INT *)); -Term STD_PROTO(Yap_gmp_and_big_big,(MP_INT *, MP_INT *)); -Term STD_PROTO(Yap_gmp_ior_big_big,(MP_INT *, MP_INT *)); -Term STD_PROTO(Yap_gmp_mod_big_big,(MP_INT *, MP_INT *)); -Term STD_PROTO(Yap_gmp_mod_big_int,(MP_INT *, Int)); -Term STD_PROTO(Yap_gmp_mod_int_big,(Int, MP_INT *)); -Term STD_PROTO(Yap_gmp_exp_ints,(Int,Int)); -Term STD_PROTO(Yap_gmp_exp_big_int,(MP_INT *,Int)); +Term STD_PROTO(Yap_gmp_add_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_sub_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_sub_big_int,(Term, Int)); +Term STD_PROTO(Yap_gmp_mul_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_div_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_div_big_int,(Term, Int)); +Term STD_PROTO(Yap_gmp_fdiv_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_fdiv_big_int,(Term, Int)); +Term STD_PROTO(Yap_gmp_and_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_ior_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_xor_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_sll_big_int,(Term, Int)); +Term STD_PROTO(Yap_gmp_add_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_sub_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_mul_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_div_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_fdiv_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_and_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_ior_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_xor_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_mod_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_mod_big_int,(Term, Int)); +Term STD_PROTO(Yap_gmp_mod_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_rem_big_big,(Term, Term)); +Term STD_PROTO(Yap_gmp_rem_big_int,(Term, Int)); +Term STD_PROTO(Yap_gmp_rem_int_big,(Int, Term)); +Term STD_PROTO(Yap_gmp_exp_int_int,(Int,Int)); +Term STD_PROTO(Yap_gmp_exp_int_big,(Int,Term)); +Term STD_PROTO(Yap_gmp_exp_big_int,(Term,Int)); +Term STD_PROTO(Yap_gmp_exp_big_big,(Term,Term)); +Term STD_PROTO(Yap_gmp_gcd_int_big,(Int,Term)); +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_add_float_big,(Float, MP_INT *)); -Term STD_PROTO(Yap_gmp_sub_float_big,(Float, MP_INT *)); -Term STD_PROTO(Yap_gmp_sub_big_float,(MP_INT *, Float)); -Term STD_PROTO(Yap_gmp_mul_float_big,(Float, MP_INT *)); +Float STD_PROTO(Yap_gmp_to_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_big_float,(Term, Float)); +Term STD_PROTO(Yap_gmp_mul_float_big,(Float, Term)); +Term STD_PROTO(Yap_gmp_fdiv_float_big,(Float, Term)); +Term STD_PROTO(Yap_gmp_fdiv_big_float,(Term, Float)); + +int STD_PROTO(Yap_gmp_cmp_big_int,(Term, Int)); +#define Yap_gmp_cmp_int_big(I, T) (-Yap_gmp_cmp_big_int(T, I)) +int STD_PROTO(Yap_gmp_cmp_big_float,(Term, Float)); +#define Yap_gmp_cmp_float_big(D, T) (-Yap_gmp_cmp_big_float(T, D)) +int STD_PROTO(Yap_gmp_cmp_big_big,(Term, Term)); + +Term STD_PROTO(Yap_gmp_neg_int,(Int)); +Term STD_PROTO(Yap_gmp_neg_big,(Term)); +Term STD_PROTO(Yap_gmp_unot_big,(Term)); + + #endif inline EXTERN Term Yap_Mk64IntegerTerm(YAP_LONG_LONG);