How to run pengines and call it from external server

Hey guys, again i have a few questions. I want to call Prolog with wordpress and i think pengines is a good choice for this ( like you guys recommended to me ). My problem now is, that i dont get how pengines work or how to setup something. I’ve read those sources:
https://pengines.swi-prolog.org/docs/documentation.html
https://www.swi-prolog.org/pldoc/doc_for?object=section(‘packages/pengines.html’)

I’ve also downloaded Pengines and can start the demo but I dont get how i can work on my own stuff. It seems that there is no tutorial or something like this out there or do you have some resources?

Actually what i need to know is the following:
I need to start a pengines server and call it with the pengines javascript api. So the javascript file is located on a different server in a wordpress installation (for now everything on localhost), so that i can use the power of prolog and pengine in wordpress. But how do i set up pengines the right way? If i just start the pengine server and try to run js file given here section('packages/pengines.html') for example, it just does nothing.

One thing i also dont get is, that every example is including “pengines.js”, but pengines.js doesnt even exist in the pengines-master download file.

Its a bit confusing. You (typically) do not want the pengines repo. The core functionality is part of the core distribution. To create a basic pengine server:

:- use_module(library(http/http_server)).
:- use_module(library(pengines)).

server(Port) :-
    http_server([port(Port)]).

To show it operational, put the above in a file, load it and run e.g., ?- server(8000). Now, to show it works we use the Prolog client from another terminal:

swipl
?- use_module(library(pengines)).
true
?- pengine_rpc('http://localhost:8000/', member(X, [a,b])).
X = a ;
X = b.

Now it all depends what client you to use. You can call the server from JavaScript. Then you need to load pengines.js , which you get /pengine/pengines.js from the pengines server. Best is to get it from there as that is guaranteed to get a file that is compatible with the server. You find several other clients at swish/client at master · SWI-Prolog/swish · GitHub

You may (but do not need to) use SWISH as your pengine server. That allows remote editing and management of Prolog scripts. That depends mostly on the role of the Prolog code plays and who is creating and maintaining that code.

2 Likes

By the way, the javascript pengine client library, pengines.js, is part of the standard distribution, you can find it here:

 /usr/lib/swipl/library/http/web/js/pengines.js

Simple HTML example calling a predicate on a pengines server (swish in this case)

This is the html example from swish/client at master · SWI-Prolog/swish · GitHub. It calls the sin_table(X,Y) predicate on the pengines server to fill a sine table on the browser.

<!DOCTYPE HTML>

<html>
<head>
  <meta charset="UTF-8">
  <title>Create sine table using Pengines</title>
  <script src="https://code.jquery.com/jquery-2.1.3.min.js"
          type="text/javascript">
  </script>
  <script src="https://swish.swi-prolog.org/pengine/pengines.js"
          type="text/javascript">
  </script>
</head>
<body>

<h1>Extract results from a Pengine/SWISH server</h1>

<p>
The table below is filled by running a query against the main SWISH
server at <a
href="https://swish.swi-prolog.org">https://swish.swi-prolog.org</a>,
using the saved script <a
href="https://swish.swi-prolog.org/p/sin_table.pl">sin_table.pl</a>.  Note that this
example illustrates that you can write interactive web applications
against one or more Pengine enabled Prolog servers without having
direct access to Prolog.

<table id="sin">
<tr><th>X<th>Y</tr>
</table>

<script type="text/x-prolog">
% Include a script saved on the server, combine it with your code here.
:- include(sin_table).
</script>

<script type="text/javascript">
/*
Create a Prolog engine running the code   from  the above script and the
query specified in `ask`. Get the results in chunks of max 1,000 entries
and ask for more results if there are more available.
*/

$(function() {
  new Pengine({ server: "https://swish.swi-prolog.org/pengine",
		ask: "sin_table(X,Y)",
		chunk: 1000,
		application: "swish",
		onsuccess: function(result) {
		  for(var i=0; i<result.data.length; i++) {
		    var b = result.data[i];
		    $("#sin").append("<tr><td>"+b.X+"<td>"+b.Y+"</tr>");
		  }
		  if ( result.more )
                    result.pengine.next();
	    }
  });
});
</script>



</body>
</html>
3 Likes

You guys are awesome thanks! Ive thought that pengines is like a standalone system and i didnt get, that i can use it just with the core distribution of swiprolog. I will try this out and think now i can handle it! Thanks :slight_smile:

one question here. does this mean i can use prolog just by calling the swish.swi-prolog server? So i could create a website, put my logic into a <script type="text/x-prolog"> tag and this logic would be processed by https://swish.swi-prolog.org/pengine?
If yes, is it possible to make this real interactive? Like the server sends an input request, the client answers, based on this answer the server again sends an input request or a result if finished?
Thanks :slight_smile:

Yes, you can do that. You can keep state on the server, but not permanently. You can only do so inside a Pengine and thus you need to create one and keep interacting with that one. Pengines die after exceeding their CPU limit or idle limit. And please be a bit gentle with the server :slight_smile:

If you run your own server you can load a library that maintains state, either talking to a database or storing it in Prolog. Next you define the interface of this library safe for the sandbox and now you can maintain state. You can also tweak access and the limits to suit your needs.

1 Like