Delphi library for SWI-Prolog

Hello,
I am making a Delphi library for SWI-Prolog, which is a direct translation of the C-API. It’s not a complete translation yet, but the major parts are there, and it was enough to embed Prolog in one of my programs.

How would I go about publishing this interface?

P.S.: There were old versions somewhere on the web, but all links were dead, including on archive.org. So I made a new one, which makes sense also, since Delphi transitioned to Unicode since those previous interfaces where current, which changed a few “rules”.

1 Like

Great! I don’t know how that will typically be deployed. Does it turn Prolog into a library for Delphi? In that case use Delphi channels might be the choice. If it is more like a Prolog library, the add-on/pack infrastructure is an easy way to distribute and make sure people can find it. If distributing as a github repo is most appropriate we can also create a link from somewhere on the website. I’m also happy to have such git repositories in the SWI-Prolog github organization. In that case we add a contrib-delhi repo, a delphi team and make you member.

It references libswipl.dll (and some dependencies it needs), just like SWI-Prolog.h. I think it would be good to create a link on the website so people can find it, when they want to embed it in Delphi programs.

It’s currently a single source file (.pas), and I would publish it on github so it can be easily maintained. An idea would be to add a translation of the simple C examples, to get people started. Possibly adding instructions for usage as well.

I am fine with publishing it on SWI-Prolog’s github or my own (or both), as you wish.

Hello,

I have been using Lazarus/FreePascal with Swi Prolog these last ten years.

I started with Mikhail Balabanov’s declaration file and made a few minor changes. I saved the unit on my website and posted the link here a few years ago. (Someone here was searching for Mikhail Balabanov’s unit).

I uploaded it again : http://geometrix.free.fr/swi_freepascal/swiprolog.pas

Hope it helps.

Thanks for providing it again, it was probably the one with the broken link.

Since I couldn’t find it, I have written it from scratch now, but maybe I can use it to check if anything is wrong. It seems to use PChar instead of PAnsiChar however, so I would have to check the other types as well.

I tried using h2pas from FreePascal first, but the macros made it choke, so I wrote it completely from hand.

I’ll upload it on GitHub soon, and send a link, and then we can see where we go from there. An official inclusion somewhere would be ideal, as mentioned in earlier posts.

One thing I noticed is that you/Mikhail defined records as packed. I couldn’t see any packing directives in the SWI-Prolog.h file, but maybe there are somewhere else. Many Windows-API headers however do not pack records explicitly, especially so they align properly on 64 bit.

Do you know anything more about this?

No.

I did not change a single line of Mikhail’s code and I have been using it everyday since 2010. I simply added a few constants.

I have also used it with Linux with success (replacing ‘libswipl.dll’ by external ‘libpl.so’). Once, in 2010.

I use FreePascal/Lazarus, Swi Prolog and Yap.

Data passed from Pascal to Swi :
strings, widestrings, numbers.

Data passed from Swi to Pascal :
atoms, strings, numbers, lists of atoms or strings.

I never, never use non deterministic calls of predicates from Pascal (PL_Retry). I use findall and the like in Prolog, gather the data into lists of atoms and pass them to Pascal.

The software is a tutorial system to help students in a situation of resolution of problems of demonstration and construction in plane Geometry.

Lazarus is used to build the graphical interface and both Prologs for the 3 inference engines. Data are huge. “Simple” geometry problems usually amount to the production of tens of thousands of facts. Half a million is not rare.

Speed is the main concern… absolutely. The C interface is much faster than the use of sockets but I also use some sockets.

I have made a few tools along these years that may be useful. They are tightly connected with my needs though. Perhaps I could make some examples out of them.

Best wishes

Could you comment on the packing of structures in the .h file?

Note that using the R Rserve interface we can compute the average of a list of 1M Prolog integers in 0.1 seconds. See https://swish.swi-prolog.org/example/Rbasics.swinb for a demo. Sockets are pretty fast provided:

  • Fast (e.g., localhost) network
  • Binary data transfer
  • Few large messages rather than many small ones. Many small messages cause large amounts of context switches.

AFAIK the XSB InterProlog project uses binary data transfer over sockets. A fast wrapper around Google protocol buffers is another option (there is a wrapper, but rather slow).

There are no packing directives in the SWI-Prolog headers, so C standard layout applies to them. I don’t think a full standard that defines the exact offsets exists though :frowning: There are only a few structures in the interface though, mostly related to blobs and streams.

Thank you Jan for those informations.

I have always felt gently pushed towards sockets and servers… :slight_smile:

I indeed use the C interface for all the short messages. I have no choice. Many triggered events are bound to the searching of the database. The simple crossing of any singe pixel by the mouse will launch a search and get a few short strings or lists back. Indexing is capital. Deep nested indexing all the more. I use many functors (mainly for readibilty reasons).

Once the main inference engine has finished its job, it sends the sometimes huge database (frequently > 100 Mb) to the core of the program through sockets.

You should be happy with last years enhancement to indexing :slight_smile:

I am indeed. :slightly_smiling_face:

Where can I find it on GitHub?

Do you have a working example of calling PL_initialise from Delphi?