Did you know ... Search Documentation:
SWI-Prolog's features

Overview

SWI-Prolog is a versatile implementation of the Prolog language. Although SWI-Prolog gained its popularity primarily in education, its development is mostly driven by the needs for application development. This is facilitated by a rich interface to other IT components by supporting many document types and (network) protocols as well as a comprehensive low-level interface to C that is the basis for high-level interfaces to C++, Java (bundled), C#, Python, Rust, etc. (externally available). Data type extensions such as dicts and strings as well as full support for Unicode and unbounded integers simplify smooth exchange of data with other components.

SWI-Prolog aims at scalability. Its robust support for multi-threading exploits multi-core hardware efficiently and simplifies embedding in concurrent applications. Its Just In Time Indexing (JITI) provides transparent and efficient support for predicates with millions of clauses.

SWI-Prolog unifies many extensions of the core language that have been developed in the Prolog community such as tabling, constraints, global variables, destructive assignment, delimited continuations and interactors.

SWI-Prolog offers a variety of development tools, most of which may be combined at will. The native system provides an editor written in Prolog that is a close clone of Emacs. It provides semantic highlighting based on real time analysis of the code by the Prolog system itself. Complementary tools include a graphical debugger, profiler, coverage analysis and cross-referencer. Alternatively, there is a mode for GNU-Emacs and, Eclipse plugin called PDT and a VSC plugin, each of which may be combined with the native graphical tools. Finally, a computational notebook and web based IDE is provided by SWISH. SWISH is a versatile tool that can be configured and extended to suit many different scenarios.

SWI-Prolog provides an add-on distribution and installation mechanism called packs. A pack is a directory with minimal organizational conventions and a control file that describes the origin, version, dependencies and automatic upgrade support. Packs can be installed from an archive, GIT repository or URL using pack_install/1. Packs are used to share code in the community. The pack system has grown a couple of eco systems for dealing with types, coroutining, etc.

Server applications

SWI-Prolog is equipped with an extensive web server (HTTP) framework that can be used both for providing (REST) services and end-user applications based on HTML5+CSS+JavaScript. Pengines (Prolog engines) allow clients to run queries against a client-provided program on a remote server using a generic API. Such programs can be executed in a sandbox.

For (web) server support SWI-Prolog provides scalable multi threading. We measured an 80 times speedup running on a 128 core power pc system. This feature makes SWI-Prolog attractive for CPU intensive server tasks where multiple clients require access to a large shared and possibly dynamic dataset. Note that many other high-level languages such as Python and Node.js only use a single core and switch between tasks based on blocking I/O. This approach generally provides good resource usage for I/O intensive services with a high number of connections but a task blocking on a computation delays all other clients. As SWI-Prolog's global garbage collectors for atoms and removed dynamic clauses run fully asynchronous in a dedicated thread, its (soft) real time behaviour is excellent.

SWI-Prolog has several unique features that reduce the need to restart servers for fixing bugs or injecting diagnostic code. Its incremental compilation combined with generally local and backtrackable data structures (undo) allows for patching the program without restarting. SWI-Prolog allows for reloading running code from another thread safely, provided the signature of the running predicates is not changed. This implies it is allowed to add, remove and modify clauses but it is not allowed to add, remove or reorder arguments. Still, this feature is valuable for hot-fixing servers or inject diagnostic code to a server without restarting.

Prolog as unifying language

Although Prolog is widely recognised as a special purpose language for tasks such as rule evaluation we consider it primarily a platform that is suitable to be used as glue between various components. The main reason for this is that data is at the core of many modern applications while there is a large variety in which data is structured and stored. Classical query languages such as SQL, SPARQL, XPATH, etc. can each deal with one such format only, while Prolog can provide a concise and natural query language for each of these formats that can either be executed directly or be compiled into dedicated query language expressions. Prolog's relational paradigm fits well with tabular data (RDBMS), while optimized support for recursive code fits well with tree and graph shaped data (RDF).

Prolog is a suitable language for Domain Specific Languages (DSL). SWI-Prolog has improved this support by syntactical extensions to the Prolog language. Examples of valid syntax that can be processed unambiguously are a[1][2], point{x:1, y:1} and function(). In addition, quasi quotations allow for safe and clean integration with the syntax of arbitrary languages. For example, the following statement specifies a fragment of JavaScript with a safe interpolation of the Prolog value X.

{|javascript(X)||var x = X;|}

Feature list

Below is a list of what we consider key features of SWI-Prolog with links to the relevant documentation.

Engine

  • fast compilation. E.g., loads WordNet 3.0 in 7 seconds from the Prolog source or 0.25 seconds from quick load file format (see qcompile/1). The WordNet source counts 821,515 lines. System: Ubuntu 22.04 on AMD 3950X, 64Gb memory.
  • Robust and free of memory leaks. In use for several servers that run 24x7 (including this web service).
  • Small. The full development environment, including graphics, libraries and many interface packages, requires approximately 70MB hard disk. The kernel is about 1.6MB (Ubuntu 22.04 .so file)
  • Scales well for large applications. No limits on program size, atom length, term arity or integer values. No performance degradation on predicates with many (indexed) facts.
  • Just-In-Time indexing of both static and dynamic code on any argument greatly simplifies handling multi-moded relations with many clauses. As of version 7.5, multi-argument JITI is supported. This creates an index for the combined value of two arguments if there is no selective single-argument index. As of version 7.7 we also support indexing on the arguments of compound terms. This feature notably improves the performance for handling terminals in grammar rules (DCGs).
  • Unbounded integer and rational number arithmetic based on GMP library.
  • The goodies: modules (upward compatible to Quintus and SICStus), garbage-collection (transparent to C/C++-code, including atom and clause garbage collection), last-call optimisation, dynamic expansion of the runtime stacks, exception-handling (including C/C++ interface for both catching and throwing exceptions).
  • attributed variables, coroutining (freeze/2, when/2, dif/2), global variables, cyclic terms.
  • Flag-controlled handling of occurs-check (false/true/error) see current_prolog_flag/2. Efficient implementation of occurs checking that only verifies that new bindings do not introduce cycles.
  • UNICODE character set handling internal. Ideal for web and international applications.
  • Multi-threading support: run multiple pre-emptively scheduled prolog engines on the same database.
  • Engines, also known as interactors provide coroutines that can be used for state accumulation and massive concurrency for e.g., swarm intelligence and simulations.
  • Delimited continuations is a powerful building block for new control structures and realise aspect programming.
  • Tabling (SLG resolution) provides a more robust resolution technique for solving queries over complex interrelated rules with guaranteed termination.
  • Following XSB, the 8.1.x development series provide well founded semantics for negation as well as incremental tabling to automatically update affected tabling with a changing knowledge base. This provides Datalog style deductive database features.

Constraint handling

Connectivity

  • SWI-Prolog provides extensive client and server libraries for HTTP. The HTTP server framework deals with generating HTML, exchange of JSON or XML, authentication, sessions, and much more. Both client and server supports HTTPS.
  • Interfaces to Redis, STOMP and ROS2 provide seemless integration in micro services frameworks. ROS2 is used for robotics services. SWI-Prolog's ROS2 binding is several times faster than the Python binding while it is capable of handling multiple requests concurrently.
  • Flexible and fast interface to the C- and C++-language. The interface allows for calling both ways, handling of non-determinism both ways and embedding of the SWI-Prolog kernel in C/C++ projects.
    • Bundled interface to Java named JPL
    • Bundled interface to Python named Janus. Janus allows for embedding Python into Prolog as well as Prolog into Python. Janus is also available for XSB.
  • Externally available interfaces to Rust, C# and more.
  • Database connectivity is provided by the ODBC interface.
  • Low level network support includes sockets (both TCP and UDP), SSL and TIPC.
  • Libraries for parsing and generating SGML/XML/HTML, JSON and YAML
  • Linked Data (RDF) support includes reading and writing many RDF formats (RDF/XML, Turtle, Ntriples, NQuads) and an efficient triple store. See the semweb package.

Development tools

  • Source-level debugger on all platforms that supports graphics through XPCE (Windows, Unix/Linux, MacOSX).
  • Execution profiler.md (time and call statistics) for all major platforms (Windows, Linux, MacOSX).
  • Coverage analysis using show_coverage/2 may be used to get line-by-line annotated versions of which parts of your source are used how many times.
  • Cross-Referencer. gxref/0 provides a graphical front-end for the extensible Prolog cross-referencer (xref).
  • Literate programming support through PlDoc. Provides integrated view on manual and application documentation and producing LaTeX documentation for your application.
  • Unit testing support through PlUnit.
  • SWISH provides a web-based platform for developing and running Prolog code in a collaborative environment.

Compatibility

  • Comprehensive set of built-in predicates, covering Part 1 of the ISO standard, the de-facto Edinburgh Prolog standard and important parts of Quintus and SICStus Prolog. Fair compatibility to Ciao, YAP and GNU-Prolog. Although the aim is to maintain compatibility wherever possible, SWI-Prolog deliberately deviates from the ISO standard to accommodate additional functionality and synchronise with modern languages. Read more in Extensions and Directions

Portability

  • Portable to many platforms, including almost all Unix/Linux platforms, Windows, MacOS X (using Xquartz for graphics) WebAssembly (WASM), Android Termux and many more. Both 32-bit and 64-bit hardware is supported. SWI-Prolog has been compiled and tested on many CPUs, e.g., x86, x64, SPARC, PowerPC, many ARM models including Apple's M1. Sources are plain C11, configured using CMake. Support for cross-compilation is steadily improving.
  • Machine-independent saved-states (save on one platform, run using the virtual machine of another platform).
  • Regular binary distributions for Windows (32/64 bits) and MacOS X (64 bits)), PPAs for Ubuntu (stable as well as development), SNAP and Docker
  • Regular distribution of the full source packages. The sources are also accessible through GIT.

Legal

  • SWI-Prolog is distributed under the Simplified BSD license, also known as the BSD-2 license. Some of the used libraries and extension packages have different license conditions. The licenses applicable to a running configuration can be examined by running license/0. See license.md for details.