Integrating a shared library in a module

Hi,

It took a few years, but the C++ client I developed for Basex is finally available. The source code for the shared library can be downloaded from GitHub - BenEngbers/libBasexCpp: C++ client for BaseX · GitHub or via Clients | BaseX 11 Documentation . The number of functions exported by the library is limited, so writing the necessary C wrappers and compiling them into a module should take relatively little time.
Before I start development work, I nowadays often ask chat.mistral.ai what the best approach is. When I asked how to integrate a shared library into a module, I received this code as an example,
:- module(basex_client, [
create_session/5,
create_db/2,
close_session/1
]).

:- use_foreign_library(‘./libbasexclient.so’).
create_session(Username, Password, Host, Port, Session) :-
foreign(basex_client_create, c, BasexClient_Create(+string, +string, +string, +integer, [-pointer])).
create_db(Session, DBName) :-
foreign(basex_client_create_db, c, BasexClient_CreateDB(+pointer, +string)).
close_session(Session) :-
foreign(basex_client_close, c, BasexClient_Close(+pointer)).

I looked on the SWI-Prolog website for more information but couldn’t find anything about the ‘foreign’ predicate, only about ‘PL_foreign’.
My question is whether Mistral now has access to more recent information about the foreign language interface?
Where can I find the most recent information?

Best regards

If your code is in C++, please look here: SWI-Prolog -- A C++ interface to SWI-Prolog
There are pointers to sample code in section 1.3.
For a larger example in C++: GitHub - JanWielemaker/rocksdb: SWI-Prolog interface for RocksDB · GitHub

It is mixing SWI-Prolog style foreign API with Quintus style. Forget it. Instead, look at the various packages and see how it is done.

Thank you for your answers.

An explanation of my plans.

The similarity between a Prolog database (the collection of “facts” can be thought of as one large database) and an XML database is that both operate without a schema. To query the Prolog database, you use the Prolog language; to query a Basex database, you use XQuery.

My research question is whether there are advantages to combining both languages. For example, I can imagine that Prolog determines which data should be retrieved from an XML database, after which that data is then used again by Prolog.

Is this a realistic research question?

Isn’t the standard thing to map your custom database into a prolog interface ?
so instead of directly using XQuery, you would translate a predicate call into XQuery, which allows you to freely mix the use of the prolog database and your custom database in prolog code.

Do you have a small self-contained example so we could discuss it further ?

You might want to look at this: GitHub - JanWielemaker/rocks-predicates: Put predicates into a RocksDB database · GitHub
which provides a generic way of storing predicates in a RocksDB. I had started to extend this (exploiting SWI-Prolog’s JIT indexing) but got distracted.

I presume you’ve looked at

etc

In https://github.com/BenEngbers/libBasexCpp/libBasexTest you can find libBasexTest.cpp. This file contains test for all functions which are mentiond in the client protocol.

Below you see some of the tests with their output. What I want to realize is just what you suggest; that you build the predicates in Prolog and send them to the database. So no,I don’have a selfcontained example (yet).

cout << "\\n9 Test Query 'for $i in 1 to 2 return $i'" << endl;std::string query = “for $i in 1 to 2 return $i”;

Output:
1
2

Q_Object = Session.Query(query);

cout << Q_Object -> getQueryString() << endl;

Q_Object -> Execute();

cout << Q_Object -> getResultString() << endl;

cout << "\\n10 Bind variable \\"$name\\" to \\"number\\"" << endl;

query = "declare variable $name external; for $i in 1 to 2 return element { $name } { $i }";

Q_Object = Session.Query(query);

Q_Object -> Bind("$name", "number");

Q_Object -> Execute();

cout << Q_Object -> getResultString() << endl;

Output:

<number>1</number>
<number>2</number>

cout << "\n11 Bind \"number\" to variable \"$name\". Specify type" << endl;

	query = "declare variable $name external; for $i in 3 to 4 return element { $name } { $i}";

	Q_Object = Session.Query(query);

	cout << Q_Object -> getQueryString() << endl;

	Q_Object -> Bind("$name", "number", "xs:string");

	Q_Object -> Execute();

	cout << Q_Object -> getResultString() << endl;

Output:

<number>3</number>
<number>4</number>

In the past, I created an application that generated a graph based on data stored in a MariaDB database. I used Prolog to first convert the data to XML and then generate a GraphViz dot file. I don’t remember exactly why I chose this approach, but it was then that I became interested in working with XML and XML databases. It was also around that time that I read most of the documents you recommended.