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).
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?
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.
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 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.
Thank you Jan for those informations.
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.
You should be happy with last years enhancement to indexing
Where can I find it on GitHub?
Do you have a working example of calling
PL_initialise from Delphi?