This topic discusses running SWI-Prolog in your browser using WASM (Web Assembler).
Below we list important updates that are also handled in this wiki page when applicable.
- [2022-08-09] Fixed several build (dependency) issues. See updated build instructions.
- [2022-08-08] Fixed yield. Add auto yielding such that the browser remains responsive and queries can be aborted. Allow creating multiple files, Added persistent (using the browser
localStorage) command line history and files.
- [2022-08-03] “Native friend” mechanism for building is no longer needed.
- [2022-08-03] Added
-s ALLOW_MEMORY_GROWTH=1to allow (notably) for bigger stacks)
There are two options for running SWI-Prolog in your browser:
- Using SWISH. This is a server based solution where the actual Prolog code is executed in a sandboxed environment on a (shared) server. SWISH is a comprehensive and mature solution for running SWI-Prolog in your browser that can support many deployment options.
- Actually running it in your browser. This is accomplished by compiling the SWI-Prolog C sources using Emscripten to WASM code. The initial port has been created by @rla. @dmchurch has made some improvements. @josderoo used it to run the EYE reasoner Inspired by the Ciao playground I (@jan) took another look at the WASM port.
A very first version of running SWI-Prolog interactively in the browser was made by @rla. Since then Emscripten evolved and so did the configuration for SWI-Prolog. I have combined the basic test code and @rla’s initial shell to make something that at least performs the very basic tasks. It is online at
Note that an alternative solution is run Prolog in a web worker. This however isolates Prolog from the page, requiring postMessage() to be used to communicate between the page and Prolog.
The SWI-Prolog web appliance uses the Emscripten virtual file system. SWI-Prolog runs in
/prolog and the normal Prolog home, containing the boot file and libraries is in
/swipl. You can use library(shell) utilities ls/0, pwd/0, cd/1 to look around.
The editor is a simple HTML
textarea. The (Re)consult button copies the content of the textarea into a the file ‘/file.pl’ and calls consult/1 on that file. It has a dropdown to select a file and buttons to add a new file or delete a file. Files are saved to the browser’s
localStorage on page unload and reloaded on page load. The query input field provides history using the arrow up/down. The history is also saved to the browser’s
?- js_call("alert('Hello world!')").
- Unbounded integers and rational numbers (GMP)
- Foreign extensions
- A browser DOM manipulation library
- Wait for input (read, etc)
- Now deals with reading toplevel queries and prompt for more answers using yield
- auto yielding keeps the page responsive
- Yielding is still problematic
- It cannot happen if there are intermediate Prolog → WASM (C) → Prolog callbacks
- Auto yielding currently happens at the exit port. Recursive loops that call no other predicates only exit when all is done. Possibly we can also yield at the enter port (after head unification).
- Sync the API with Ciao where possible
The shell above is just a toy. It is intended as a simple platform to help debugging and resolving the above issues. A likely future scenario is to integrate the WASM based solution into SWISH.
These instructions assume Ubuntu Linux but can be adjusted to other platforms. Please edit this page if you did so for your platform of choice.
See Download and install — Emscripten 3.1.19-git (dev) documentation. These instructions install emscripten in
~/.wasm/emsdk on a Linux machine (requires about 1.1 Gb disk)
cd mkdir wasm cd wasm git clone https://github.com/emscripten-core/emsdk.git cd emsdk ./emsdk install latest ./emsdk activate latest
Now build the zlib dependency for WASM using
cd ~/wasm wget https://zlib.net/zlib-1.2.12.tar.gz tar xf zlib-1.2.12.tar.gz cd zlib-1.2.12/ source ../emsdk/emsdk_env.sh emconfigure ./configure emmake make
For dependencies, see Prerequisites for Debian based systems (Ubuntu, Mint, ...)
cd mkdir -p src cd src git clone https://github.com/SWI-Prolog/swipl-devel.git cd swipl-devel git submodule update --init
cd ~/src/swipl-devel mkdir build.wasm
Now save the following text to a new file
configure and make it executable using
chmod +x configure
WASM_HOME=$HOME/wasm source $WASM_HOME/emsdk/emsdk_env.sh TOOLCHAIN=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake [ -f $TOOLCHAIN ] || echo "Could not find emscripten toolchain" cmake -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN \ -DCMAKE_BUILD_TYPE=Release \ -DZLIB_LIBRARY=$WASM_HOME/zlib-1.2.12/libz.a \ -DZLIB_INCLUDE_DIR=$WASM_HOME/zlib-1.2.12 \ -DMULTI_THREADED=OFF \ -DUSE_SIGNALS=OFF \ -DUSE_GMP=OFF \ -DBUILD_SWIPL_LD=OFF \ -DINSTALL_DOCUMENTATION=OFF \ -G Ninja ..
Now configure and build the version in the
build.wasm directory using
To update to the latest version one should run the commands below. Removing
src/wasm-preload is required to make sure changes to the Prolog libraries are correctly incorporated in
src/swipl-web.data which populates
/swipl in the WASM version.
git pull git submodule update --init cd build.wasm rm -rf src/wasm-preload && ninja
If all went right, you can now run the wasm version using
$ node src/swipl.js Welcome to SWI-Prolog (32 bits, version 8.5.15-26-gc1ca50a94) SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software. Please run ?- license. for legal details. CMake built from "/home/janw/src/swipl-devel/build.wasm" For online help and background, visit https://www.swi-prolog.org For built-in help, use ?- help(Topic). or ?- apropos(Word). 1 ?-
The generated files for your browser are
src/swipl-web.data. The Prolog shell discussed above can be found in
swipl-devel/src/wasm/shell.html. It can be started using a Prolog based web server in the same directory named
server.pl. The server must be started in the build directory as it uses
src/swipl-web.* to find the WASM components.
cd ~/src/swipl-devel/build.wasm swipl ../src/wasm/server.pl [--port=8000]
Discourse has a plug-in (theme component) that searches post for specific text and automatically converts the text to a link (linkify).
These words with a # prefix were added for this topic
#devel_commits -To understand the changes to the code, review the GitHub commits for SWI-Prolog development repository. To make it easy to identify the link when writing a post noting the GitHub SWI-Prolog development repository commits just add
Note: That while not always most of the commits related to WASM start with the name
#wasm_demo - For those that follow along with the post actively, knowing were to find the demo site is easy. For those dropping in the middle via a Google search some years in the future it can become a needle in a haystack search for the site. To make it easy to identify the link when writing a post noting the demo site just add
#wasm_wiki - While the discussion thread gets all activity the post that has the crucial facts is not always identified in the post that discuss them. To make it easy to identify the link when writing a post noting this wiki page just add