A downside of the Pengines approach is that the Prolog is run in one module. The code sent to a pengine is executed in the context of the module pengine_sandbox
and the safety of goals is validated using safe_goal/1
prior to execution. Any pengine has access to the safe predicates defined in library(sandbox)
.
The JavaScript API I’m hoping to provide for a number of projects utilizes modules.
Here is some source code from the project. By utilizing ClearScript, I initialize a V8 JavaScript engine. Then, I initialize a custom Prolog engine which uses SWI-Prolog. Then, I add some console functionality and the Prolog engine to the JavaScript environment.
using (var engine = new V8ScriptEngine())
{
using (var prolog = new Prolog())
{
engine.AddHostType("Console", typeof(Console));
engine.AddHostObject("prolog", prolog);
Using the Prolog engine’s API, here is some JavaScript which works:
var module1 = prolog.createModule('module1');
var module2 = prolog.createModule('module2');
module1.assert('p(1, 1)');
module1.assert('p(2, 1)');
module1.assert('p(3, 1)');
module2.assert('p(a, 1)');
module2.assert('p(b, 1)');
module2.assert('p(c, 1)');
for (var r of module1.query('p(X, Y)'))
{
Console.WriteLine('p({0}, {1})', r['X'], r['Y']);
}
Console.WriteLine();
for (var r of module2.query('p(X, Y)'))
{
Console.WriteLine('p({0}, {1})', r.X, r.Y);
}
Console.WriteLine();
module1.assertRule('p2(X)', 'p(X, X)');
for (var r of module1.query('p2(X)'))
{
Console.WriteLine('p2({0})', r.X);
}
module1.addPredicate('p3', 2, function(x, y) { return x.toInteger() > y.toInteger(); });
if (module1.contains('p3(2, 1)')) { Console.WriteLine('2 > 1'); }
if (!module1.contains('p3(1, 2)')) { Console.WriteLine('1 <= 2'); }
The API provides developers with multiple modules, which differs from the Pengines approach. Also, one can observe the smooth registration of foreign predicates from JavaScript with addPredicate
.
In summary, the API desires to provide developers with multiple modules and pengines executes Prolog in the context of one module, pengine_sandbox
, and validates the safety of goals using safe_goal/1
.
What I’m hoping for is one or more flags to initialize SWI-Prolog with so that it only loads a very minimal set of Prolog functionality. In this way, we could secure or sandbox SWI-Prolog while providing use of multiple modules to developers.