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.