Setting Up Your Prolog Development Environment
In this chapter we will install SWI-Prolog and configure a productive development environment. SWI-Prolog is the primary Prolog system used throughout this book.
Installing SWI-Prolog
macOS
On macOS, the most straightforward way to install SWI-Prolog is using the Homebrew package manager. Run the following command in your terminal:
1 brew install swi-prolog
This installs the stable version of SWI-Prolog, including the core execution engine, compiler, interactive top level (swipl), and development utilities.
Building from Source on macOS
If you prefer to build SWI-Prolog from source on macOS (for example, to enable optional modules or custom compile configurations), first install the required build dependencies via Homebrew:
1 brew install cmake ninja gmp openssl readline jpeg libarchive libyaml pcre2 pkg-config
Then, clone the official SWI-Prolog repository recursively to fetch all git submodules:
1 git clone --recursive https://github.com/SWI-Prolog/swipl-devel.git
2 cd swipl-devel
3 mkdir build
4 cd build
5 cmake -G Ninja ..
6 ninja
7 ninja install
Linux
SWI-Prolog is available in the package repositories of most major Linux distributions.
Debian and Ubuntu
For Debian, Ubuntu, and derivative distributions, it is highly recommended to use the official SWI-Prolog Personal Package Archive (PPA) to ensure you install the latest stable version:
1 sudo apt-add-repository ppa:swi-prolog/stable
2 sudo apt update
3 sudo apt install swi-prolog
If you prefer the latest development release instead, you can add ppa:swi-prolog/devel instead.
Fedora, Red Hat, and CentOS
On Fedora or other systems using the dnf package manager, install SWI-Prolog with:
1 sudo dnf install swipl
Windows
For Windows environments, precompiled binaries and installers are provided directly:
- Visit the stable download page: https://www.swi-prolog.org/download/stable.
- Download the appropriate 64-bit installer for Windows.
- Run the installer and proceed through the setup wizard.
- Important: During the installation, make sure to check the option to add the SWI-Prolog bin directory to the system
PATHenvironment variable. This allows you to launch the REPL by runningswiplfrom command prompts or terminal windows (such as Command Prompt, PowerShell, or WSL).
Editor Support
Writing Prolog is much more productive when using an editor configured with syntax highlighting, auto-indentation, and interactive execution helper tools.
Visual Studio Code (VS Code)
VS Code is the most popular modern text editor for Prolog development:
- Recommended Extension: Search for and install the VSC-Prolog extension (by Arthur Wang).
- Features: Offers syntax highlighting, automatic linter feedback, tooltips with predicate signatures, and the ability to load your current file into an integrated SWI-Prolog REPL terminal.
- Configuring the Executable: If the extension displays an error indicating it cannot locate the Prolog engine, open your settings (
Ctrl+,orCmd+,) and setprolog.executablePathto the path of yourswiplinstallation (e.g.,/usr/local/bin/swiplon macOS/Linux, orC:\Program Files\swipl\bin\swipl.exeon Windows).
Emacs
Emacs provides a classic, keyboard-driven environment with first-class support for SWI-Prolog:
- Recommended Mode: The built-in
prolog-mode(which has specialized configurations optimized for SWI-Prolog). - Features: Auto-indentation, syntax coloring, query execution, and the ability to run an interactive sub-process (
M-x run-prolog) that compiles buffers dynamically. -
Configuration: Add the following setup code to your Emacs init file (
init.el):1 (setq prolog-system 'swi)
The Built-in SWI-Prolog Editor (PceEmacs)
SWI-Prolog features a built-in GUI text editor based on its native graphical toolkit (XPCE). You can start the editor directly from the REPL shell:
1 ?- emacs.
To edit a specific file directly, run:
1 ?- edit(my_file).
This editor integrates tightly with the runtime engine, enabling semantic highlighting, immediate compilation error feedback, and quick navigation to predicate definitions.
The SWI-Prolog Interactive Top Level
The interactive top level—often referred to as the REPL (Read-Eval-Print Loop)—is where you query and test your code.
Starting and Exiting the REPL
To start the REPL, open your terminal and run the swipl command:
1 $ swipl
2 Welcome to SWI-Prolog (threaded, 64 bits, version 9.2.0)
3 ...
4 ?-
To exit the REPL, type the halt/0 predicate followed by a period:
1 ?- halt.
Alternatively, you can press Ctrl-D (on macOS/Linux) or Ctrl-Z followed by Enter (on Windows).
Loading and Reloading Files
To load (or “consult”) a local source file named family.pl:
1 ?- [family].
Note that the .pl extension is assumed automatically, and the query must end with a period.
If you modify family.pl in an external editor, reload the changes into the current REPL session with:
1 ?- make.
The make/0 predicate automatically checks for modified files and recompiles them.
Querying and Backtracking
Prolog queries are evaluated left-to-right. If variables are present, the REPL presents the first matching solution it finds.
- To search for more solutions, press the
;(semicolon) key. - To accept the current solution and return to the main prompt, press the
Enterkey (or.).
1 ?- parent(tom, Child).
2 Child = bob ;
3 Child = liz.
Tracing and Debugging
SWI-Prolog includes a comprehensive debugging console based on the 4-port debugger model (Call, Exit, Redo, Fail):
- Enable Tracing: Type
trace.and then run your query. The console will pause at every evaluation port. - Stepping: During a trace, press the Spacebar to creep (step in) or
sto skip (step over). Presshto display a menu of all trace options. - Disable Tracing: Turn the debugger off using
notrace.. - Spy Points: If you only want to debug a specific predicate, set a spy point:
spy(my_predicate/2).. -
Graphical Debugger: If you are in a GUI environment, you can open the visual debugger window:
1 ?- gtrace, my_query(X).
Getting Help
Query the built-in manuals directly from the REPL:
-
Search for predicate documentation:
1 ?- help(append/3).
-
Keyword search:
1 ?- apropos(list).
Installing Packs (Libraries)
SWI-Prolog includes a package manager for distributing community-contributed libraries, referred to as packs.
Searching and Installing
To install a package, call pack_install/1 with the pack name:
1 ?- pack_install(regex).
This retrieves the pack from the central repository, configures it, compiles any native foreign components (if needed), and installs it under your user configuration folder.
Pack Management Commands
-
List installed packages:
1 ?- pack_list('').
-
Upgrade a package to the latest version:
1 ?- pack_upgrade(regex).
-
Uninstall a package:
1 ?- pack_remove(regex).
Cloning the Book’s GitHub Repository
First, clone the GitHub repository that contains the example programs and the manuscript files for this book:
1 git clone https://github.com/mark-watson/PrologAIBook.git
Directory Structure Overview
The cloned repository contains two primary directories:
manuscript/: This folder contains the markdown chapters of the book.-
source-code/: This folder contains all the companion Prolog projects, which are structured as modular codebases with tests. Here are some of the key source subdirectories:tutorial_basics/: Entry-level programs covering lists, rules, and basic DCGs.expert_shell/: A backward-chaining expert system engine that generates natural explanations.scasp_compliance/: Code implementing regulatory compliance checks using thes(CASP)reasoning engine.janus_ml_python_interop/: Interfacing Prolog directly with Python machine learning libraries using Janus.prolog_wasm_web/: Code examples compiling Prolog logic to run client-side in the web browser via WebAssembly.llm_logic_guardrails/: Structuring prompts, sending LLM queries, and verifying responses against formal logic guardrails.agent_behavior_trees/: Implementing reactive logic-based behavior trees for agent action planning.
Project Organization and Best Practices
Setting up a robust SWI-Prolog project involves adopting package management conventions (even if you aren’t publishing it publicly) and utilizing the built-in module and testing systems. Here is the standard approach to structuring, managing dependencies, and testing in SWI-Prolog.
Standard Project Layout
The most idiomatic way to structure a modern SWI-Prolog project mimics its package manager (pack) layout. This cleanly separates metadata, source code, and tests.
1 my_project/
2 ├── pack.pl # Project metadata and dependencies
3 ├── load.pl # Main entry point / bootstrapper
4 ├── prolog/ # Application source files
5 │ ├── core.pl
6 │ └── utils.pl
7 └── tests/ # Unit tests (plunit)
8 ├── test_core.pl
9 └── test_utils.pl
- prolog/: Contains your actual logic. Every file here should be a module.
- load.pl: A convenience script used to load your application into the REPL. It typically contains directives like
:- use_module(prolog/core). - tests/: Kept separate from source code to avoid polluting the production footprint.
Defining Dependencies with pack.pl
SWI-Prolog manages dependencies via the pack.pl file located at the project root. This file contains Prolog terms declaring metadata and required libraries (both built-in and external packs).
Example pack.pl:
1 name(my_project).
2 version('0.1.0').
3 title('A concise Prolog application').
4 author('Your Name', 'email@example.com').
5
6 % Dependencies
7 requires(http). % Built-in SWI-Prolog library
8 requires(clpfd). % Constraint Logic Programming
9 requires(regex). % External pack (needs installation)
To install external dependencies defined in this file, you would run the following from the SWI-Prolog REPL in your project root:
1 ?- pack_install('.').
Organizing Source Files with Modules
To prevent predicate name collisions across a growing codebase, encapsulate your source files using SWI-Prolog’s module system. At the top of every file in your prolog/ directory, declare the module and explicitly export the predicates intended for public use.
prolog/core.pl:
1 :- module(core, [
2 process_data/2, % Exported predicate
3 evaluate_state/1 % Exported predicate
4 ]).
5
6 :- use_module(utils). % Import another local module
7 :- use_module(library(clpfd)). % Import a dependency
8
9 % Implementation
10 process_data(Input, Output) :-
11 clean_input(Input, Cleaned), % Private predicate
12 Output = Cleaned.
13
14 clean_input(X, X).
Unit Testing with PLUnit
SWI-Prolog includes the plunit testing framework natively. While you can embed tests directly inside your source modules, placing them in a dedicated tests/ directory is cleaner for larger projects.
tests/test_core.pl:
1 :- module(test_core, []).
2 :- use_module(library(plunit)).
3 :- use_module('../prolog/core').
4
5 :- begin_tests(core_logic).
6
7 test(process_data_valid) :-
8 process_data(raw_data, Output),
9 assertion(Output == raw_data).
10
11 test(fail_case, [fail]) :-
12 process_data(invalid, valid).
13
14 test(throws_error, [error(instantiation_error)]) :-
15 X is Y + 1.
16
17 :- end_tests(core_logic).
Running the Tests:
You can run your test suite from the REPL by loading the test files and executing the test runner:
1 ?- load_test_files([]).
2 ?- run_tests.
Alternatively, to test from the command line without entering the interactive REPL:
1 swipl -g "load_test_files([]), run_tests, halt" -s load.pl