npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

swipl-stdio

v1.0.4

Published

A Node.js interface to the SWI-Prolog.

Downloads

122

Readme

node-swipl-stdio

A Node.js interface to the SWI-Prolog communicating over stdio. This interface fixes multiple issues found when developing node-swipl.

The issues fixed are:

  • No native code to maintain.
  • No compiler/linker needed during installation.
  • No need to set SWI-Prolog environment variables.
  • Queries are asynchronous, not blocking the event loop.
  • Unicode atoms work correctly.
  • Dicts can be exported from SWI-Prolog.
  • Concurrent queries by using multiple engines.

Build Status

Installation:

You need to have SWI-Prolog installed and swipl binary available in PATH.

npm install swipl-stdio

Usage

The package requires Node.js version 7.6+ as it makes heavy use of promises and async/await.

Calling a predicate and returning bindings with the first solution:

const swipl = require('swipl-stdio');
// Engine represents one SWI-Prolog process.
const engine = new swipl.Engine();
(async () => {
    const result = await engine.call('member(X, [1,2,3,4])');
    if (result) {
        console.log(`Variable X value is: ${result.X}`);
    } else {
        console.log('Call failed.');
    }
    // Either run more queries or stop the engine.
    engine.close();
})().catch((err) => console.log(err));

Outputs:

Variable X value is: 1

Calling a predicate and returning all solutions:

const swipl = require('swipl-stdio');
const engine = new swipl.Engine();
(async () => {
    const query = await engine.createQuery('member(X, [1,2,3,4])');
    try {
        let result;
        while (result = await query.next()) {
            console.log(`Variable X value is: ${result.X}`);
        }
    } finally {
        await query.close();
    }
    engine.close();
})().catch((err) => console.log(err));

Outputs:

Variable X value is: 1
Variable X value is: 2
Variable X value is: 3
Variable X value is: 4

There is only one query worked on concurrently per engine. Multiple concurrent queries are queued.

Output term representation

Prolog terms in variable bindings are converted into JavaScript objects under the following rules:

  • Integers are converted to numbers.
  • Floats are converted to numbers.
  • Atoms and strings are converted to strings.
  • Empty list is converted to string [].
  • List head tail pair is converted to object { head, tail } where head and tail are converted terms.
  • Compound term is converted to object { name, args } where name is the compound functor name and args is the array of converted argument terms.
  • Dict is converted to object { tag, content } where tag is the dict tag (either string or a variable) and content is an object representing the dict contents.
  • Blobs are not supported.

Constructing safe queries

Queries with data requiring proper escaping can be constructed by using helper functions from swipl.term.

Example:

const swipl = require('swipl-stdio');
const { list, compound, variable, dict, serialize } = swipl.term;

const safe = serialize(
    compound('member', [
        variable('X'),
        list([1, 2, 3, 4])]));

console.log(safe);

Compound terms are created with the function:

compound(name, args)

Variables are created with the function:

variable(name)

Where name matches the pattern ^[A-Z_][A-Za-z0-9]*.

Lists are created with the function:

list(items)

Dicts are created with the function:

dict(tag, content)

Where tag is a string or a variable and content is an object. The properties of the content object are turned into the dict entries.

Blobs are not supported.

Debugging

Run with DEBUG=swipl node your_code.js. To write debugging output from SWI-Prolog, write to stderr.

Example:

format(user_error, 'Output to stderr.~n', []).

Or use the debug library which writes its output to stderr as well: http://www.swi-prolog.org/pldoc/man?section=debug

Normal output from SWI-Prolog (write(something)) has been also redirected through stderr.

License

The codebase uses 2-Clause BSD license. See the LICENSE file.