From d1d149b9fdd4d223d8a144a8f7d23b2b64293d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Santos=20Costa?= Date: Fri, 18 Jun 2010 23:24:36 +0100 Subject: [PATCH] support for PL_ mpz and mpq ops add missing atom_nchars --- C/gmp_support.c | 41 ++++++++++++++++++++++++++ H/eval.h | 3 ++ include/SWI-Prolog.h | 8 ++++++ library/yap2swi/yap2swi.c | 60 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+) diff --git a/C/gmp_support.c b/C/gmp_support.c index e71f2e382..b47aba05f 100755 --- a/C/gmp_support.c +++ b/C/gmp_support.c @@ -1594,6 +1594,47 @@ Yap_gmp_to_size(Term t, int base) return 1; } +int +Yap_term_to_existing_big(Term t, MP_INT *b) +{ + if (IsVarTerm(t)) + return FALSE; + if (IsIntegerTerm(t)) { + mpz_set_si(b,IntegerOfTerm(t)); + return TRUE; + } + if (IsBigIntTerm(t)) { + if (RepAppl(t)[1] != BIG_INT) + return FALSE; + mpz_set(b,Yap_BigIntOfTerm(t)); + return TRUE; + } + return FALSE; +} + +int +Yap_term_to_existing_rat(Term t, MP_RAT *b) +{ + if (IsVarTerm(t)) + return FALSE; + if (IsIntegerTerm(t)) { + mpq_set_si(b, IntegerOfTerm(t), 1); + return TRUE; + } + if (IsBigIntTerm(t)) { + CELL flag = RepAppl(t)[1]; + if (flag == BIG_INT) { + mpq_set_z(b, Yap_BigIntOfTerm(t)); + return TRUE; + } + if (flag == BIG_RATIONAL) { + mpq_set(b, Yap_BigRatOfTerm(t)); + return TRUE; + } + } + return FALSE; +} + #endif diff --git a/H/eval.h b/H/eval.h index 7f4ec6466..138916485 100644 --- a/H/eval.h +++ b/H/eval.h @@ -305,6 +305,9 @@ Term STD_PROTO(Yap_gmp_popcount,(Term)); char * STD_PROTO(Yap_gmp_to_string,(Term, char *, size_t, int)); size_t STD_PROTO(Yap_gmp_to_size,(Term, int)); + +int STD_PROTO(Yap_term_to_existing_big,(Term, MP_INT *)); +int STD_PROTO(Yap_term_to_existing_rat,(Term, MP_RAT *)); #endif inline EXTERN Term Yap_Mk64IntegerTerm(YAP_LONG_LONG); diff --git a/include/SWI-Prolog.h b/include/SWI-Prolog.h index 1d86a086a..e7d697ab8 100755 --- a/include/SWI-Prolog.h +++ b/include/SWI-Prolog.h @@ -399,6 +399,7 @@ extern X_API int PL_cons_functor_v(term_t, functor_t,term_t); extern X_API int PL_cons_list(term_t, term_t, term_t); extern X_API int PL_put_atom(term_t, atom_t); extern X_API int PL_put_atom_chars(term_t, const char *); +extern X_API int PL_put_atom_nchars(term_t, size_t ,const char *); extern X_API int PL_put_float(term_t, double); extern X_API int PL_put_functor(term_t, functor_t t); extern X_API int PL_put_int64(term_t, int64_t); @@ -561,6 +562,13 @@ PL_EXPORT(int) PL_release_stream(IOSTREAM *s); #endif +#if USE_GMP +PL_EXPORT(int) PL_get_mpz(term_t t, mpz_t mpz); +PL_EXPORT(int) PL_unify_mpz(term_t t, mpz_t mpz); +PL_EXPORT(int) PL_get_mpq(term_t t, mpq_t mpz); +PL_EXPORT(int) PL_unify_mpq(term_t t, mpq_t mpz); +#endif + extern X_API const char *PL_cwd(void); void swi_install(void); diff --git a/library/yap2swi/yap2swi.c b/library/yap2swi/yap2swi.c index a71b6fa5d..03cd7deb9 100755 --- a/library/yap2swi/yap2swi.c +++ b/library/yap2swi/yap2swi.c @@ -757,6 +757,40 @@ X_API int PL_get_int64(term_t ts, int64_t *i) } +#if USE_GMP + + /******************************* + * GMP * + *******************************/ + +X_API int PL_get_mpz(term_t t, mpz_t mpz) +{ + Term t0 = Yap_GetFromSlot(t); + + return Yap_term_to_existing_big(t0, mpz); +} + +X_API int PL_unify_mpz(term_t t, mpz_t mpz) +{ + Term iterm = Yap_MkBigIntTerm(mpz); + return Yap_unify(Yap_GetFromSlot(t),iterm); +} + +X_API int PL_get_mpq(term_t t, mpq_t mpz) +{ + Term t0 = Yap_GetFromSlot(t); + + return Yap_term_to_existing_rat(t0, mpz); +} + +X_API int PL_unify_mpq(term_t t, mpq_t mpq) +{ + Term iterm = Yap_MkBigRatTerm(mpq); + return Yap_unify(Yap_GetFromSlot(t),iterm); +} + +#endif + X_API int PL_get_list(term_t ts, term_t h, term_t tl) { YAP_Term t = Yap_GetFromSlot(ts); @@ -1092,6 +1126,32 @@ X_API int PL_put_atom_chars(term_t t, const char *s) return TRUE; } +X_API int PL_put_atom_nchars(term_t t, size_t len, const char *s) +{ + Atom at; + char *buf; + + if (strlen(s) > len) { + while (!(buf = (char *)Yap_AllocCodeSpace(len+1))) { + if (!Yap_growheap(FALSE, 0L, NULL)) { + Yap_Error(OUT_OF_HEAP_ERROR, TermNil, Yap_ErrorMessage); + return FALSE; + } + } + strncpy(buf, s, len); + } else { + buf = (char *)s; + } + while (!(at = Yap_LookupAtom(buf))) { + if (!Yap_growheap(FALSE, 0L, NULL)) { + Yap_Error(OUT_OF_HEAP_ERROR, TermNil, Yap_ErrorMessage); + return FALSE; + } + } + Yap_PutInSlot(t,MkAtomTerm(at)); + return TRUE; +} + X_API int PL_put_float(term_t t, double fl) { Yap_PutInSlot(t,YAP_MkFloatTerm(fl));