Closed ssardina closed 4 years ago
Some progress on the Java side in 9ea1a114bd5c3a92238ac05ec7dd5d0c67034d94
Hi Sebastian! You know I know little about Java and JPL, but if I can help a little on the C side close to Prolog, I'm happy to.
Hi Jan! Very timing indeed, thanks for offering to help.
In fact, I have almost finished the Java side of JPL for accommodating rationals, but the C side is my strong weak side. I have been trying to understand but it's challenging to say the least :-) And I don't want to make any bad mistake.
What I need is to build a Prolog term to represent a rational, basically a corresponding PL_put_*()
C function. While we have for integers, floats, etc there seems to be none for rational:
https://www.swi-prolog.org/pldoc/man?section=foreign-term-construct
I would imagine we need the following C function:
int PL_put_rational(term_t -t, long n, long d)
in file src/pl-fli.c
but there is none. Am I missing something why it is not there? Can we add it?
I am confused because there are some stuff about rationals there, for example:
int
PL_is_rational(term_t t)
{ GET_LD
word w = valHandle(t);
return isRational(w);
}
Interesingly though isRational(w)
compares with an integer tag code (src/pl-data.h
):
#define isRational(w) (tag(w) == TAG_INTEGER)
So, I suspect I am missing the point here. To me it seems rationals are partially supported in all this , but this cannot be right and I am not understanding it correctly.
Again, I think what I need is the PL_put_rational(term_t -t, long n, long d)
function
The relevant documentation is here. Some remarks:
TAG_INTEGER
should be read as TAG_RATIONAL
. Classical integers are a subtype of rationals.mpq
. We could provide an alternative that puts/gets two integers as you propose, but ideally this should support unbounded integers. If I remember well, we handle unbounded integers using strings, no? I guess the relevant question is what can be represented in Java and how we get this efficiently and elegantly from C (through JNI) to Java. This concerns both unbounded integers and rationals. If you can give me that I think I can decide on the best interface.Are you suggesting that I treat a rational in Java as a String, similarly as we do with BigInteger (arbitrary precision)?
Yes when we put a BigInteger into a term, we treat the number as a String and then use PL_chars_to_term
as follows:
JNIEXPORT jboolean JNICALL
Java_org_jpl7_fli_Prolog_put_1integer_1big(JNIEnv *env, jclass jProlog,
jobject jterm, jstring jvalue)
{ term_t term;
if ( jpl_ensure_pvm_init(env) &&
getTermValue(env, jterm, &term))
{ return PL_chars_to_term((char *)(*env)->GetStringUTFChars(env, jvalue, 0),
term);
} else
{ return FALSE;
}
}
See all this code is in the JNI interface jpl.c
so requires nothing from code SWI code in the FLI.
mmm would this work if I just represent the rational number a String with two numbers separated with an r
? Like 2r3
for 2/3
? Is that easy?
I guess chars_to_term
will take the chars 2r3
and covert it to a Prolog 2 rdiv 3
.. Is that true?
Sorry I am pretty basic (actually null) at the C side of SWI so most of it is "guessing" rather than true knowledge.. ;-)
BTW, shouldn't TAG_INTEGER
be renamed TAG_RATIONAL
as integers are rational, not the other way around?
Like
2r3
That would surely work. I wonder how bad it is from a performance perspective. We could consider hexadecimal notation as well, e.g., 0x2r3. This isn't yet supported (it is for big integers, but not for rational) but it does require significantly less work to read.
What about the other direction (Prolog --> Java)?
TAG_INTEGER
be renamedTAG_RATIONAL
That makes sense. The constants are not known externally though, so it is not really an issue.
SWI-Prolog can not report terms of type
rational
, which are not (yet) supported by JPL.