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”.
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.
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).
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.
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.
Note that using the R Rserve interface we can compute the average of a list of 1M Prolog integers in 0.1 seconds. See SWISH -- SWI-Prolog for SHaring 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 There are only a few structures in the interface though, mostly related to blobs and streams.
I have always felt gently pushed towards sockets and servers…
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.