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

Translated with DeepL.com (free version)

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.

1 Like

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.