Skip to content
Volume P · The TensorCore.si Library

Prolog

Programming in logic.

Prolog (PROgramming in LOGic) is a declarative language: you describe facts and rules, then ask questions, and Prolog searches for answers. It was central to symbolic AI, expert systems and natural language processing, and it is still used for rule engines, planning and, increasingly, giving LLMs reliable reasoning tools.

Prologue

Why learn Prolog?

Prolog teaches a completely different way to program, and logic reasoning is making a comeback alongside LLMs.

  • Declarative: say what is true, not how to compute it.
  • Built-in search: backtracking finds every solution automatically.
  • Neuro-symbolic AI: LLMs can write Prolog to solve logic problems reliably.
Prologue

Set up and run your first program

Install SWI-Prolog, the most popular free implementation.

terminal
sudo apt install swi-prolog
swipl hello.pl
hello.pl
:- initialization(main).

main :-
    Name = "Ada",
    format("Hello, AI! Welcome to Prolog, ~w.~n", [Name]),
    halt.
TipIn the interactive shell, load a file with [hello]. and type queries ending with a period.
Chapter 1

Facts and queries

A program is a database of facts. Ask questions (queries) and Prolog finds matching answers. Names starting with an uppercase letter are variables.

facts.pl
gpu(h100, 80).
gpu(h200, 141).
gpu(rtx5090, 32).
maker(h100, nvidia).
maker(h200, nvidia).

% Queries in the shell:
% ?- gpu(h200, Vram).        Vram = 141.
% ?- gpu(Name, 80).          Name = h100.
% ?- gpu(Name, _).           press ; for more answers
Chapter 2

Rules

Rules define new facts from old ones. :- means "if" and a comma means "and".

rules.pl
datacenter(G) :- gpu(G, V), V >= 80.
nvidia_datacenter(G) :- datacenter(G), maker(G, nvidia).
fits(Model, G) :- model_size(Model, S), gpu(G, V), S =< V.

model_size(llama8b_fp16, 16).
model_size(llama70b_fp16, 140).

% ?- datacenter(G).          G = h100 ; G = h200.
% ?- fits(llama70b_fp16, G). G = h200.
Chapter 3

Recursion and lists

Lists are written [H|T] (head and tail). Recursive rules process them; arithmetic uses is.

lists.pl
sum([], 0).
sum([H|T], S) :- sum(T, S1), S is S1 + H.

len([], 0).
len([_|T], N) :- len(T, N0), N is N0 + 1.

% ?- sum([80, 141, 180], S).          S = 401.
% ?- findall(G, datacenter(G), L).    L = [h100, h200].
% ?- member(X, [a, b, c]).            X = a ; X = b ; X = c.
Chapter 5

Parsing with DCGs

Definite Clause Grammars turn grammar rules into parsers, one reason Prolog was popular for natural language processing.

grammar.pl
sentence --> noun_phrase, verb_phrase.
noun_phrase --> [the], noun.
verb_phrase --> verb, noun_phrase.
noun --> [model] ; [gpu] ; [agent].
verb --> [uses] ; [trains].

% ?- phrase(sentence, [the, agent, uses, the, gpu]).   true.
% ?- phrase(sentence, [gpu, the, uses]).               false.
Part II · AI with Prolog

Prolog and AI

Prolog powered expert systems, Japan's Fifth Generation Computer project and parts of IBM Watson's question analysis. Today it is part of neuro-symbolic AI: an LLM translates a question into Prolog, and Prolog's exact reasoning finds the answer, which reduces mistakes on logic and maths problems.

The essential libraries

SWI-PrologFree, full-featured Prolog with web and JSON libraries.
janus-swiCall Prolog from Python and Python from Prolog.
CLP(FD)Constraint solving over integers.
http/jsonBuilt-in HTTP client and JSON support.

Constraint solving

CLP(FD) solves a scheduling puzzle declaratively.

clp.pl
:- use_module(library(clpfd)).

% Split 8 GPUs between training and inference:
% training needs at least 3x inference, inference at least 1.
split(Train, Infer) :-
    [Train, Infer] ins 1..8,
    Train + Infer #= 8,
    Train #>= 3 * Infer,
    label([Train, Infer]).

% ?- split(T, I).   T = 6, I = 2 ; T = 7, I = 1.
Part III · Build an AI agent

LLM + Prolog reasoning agent

A Python agent gives a local model a tool that runs Prolog queries through janus-swi, so the model handles language while Prolog does exact logic.

Your goal→Model plans→Tool call→Your code runs the tool→Result back to model→Final answer
agent.py
# pip install janus-swi openai   (needs SWI-Prolog 9+)
import json, janus_swi as janus
from openai import OpenAI

janus.consult("facts.pl")      # gpu/2, maker/2
janus.consult("rules.pl")      # datacenter/1, fits/2

def prolog(query):
    return json.dumps([{k: str(v) for k, v in s.items() if k != "truth"} for s in janus.query(query)])

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
tools = [{"type": "function", "function": {"name": "prolog", "description": "Run a Prolog query, e.g. fits(llama70b_fp16, G)",
    "parameters": {"type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"]}}}]
messages = [{"role": "system", "content": "Facts: gpu(Name,Vram), maker(Name,Maker), datacenter(G), fits(Model,G)."},
            {"role": "user", "content": "Which GPU can hold llama70b_fp16?"}]
for _ in range(5):
    msg = client.chat.completions.create(model="llama3.1", messages=messages, tools=tools).choices[0].message
    messages.append(msg)
    if not msg.tool_calls:
        print(msg.content); break
    for c in msg.tool_calls:
        messages.append({"role": "tool", "tool_call_id": c.id, "content": prolog(**json.loads(c.function.arguments))})

The model never guesses the answer: Prolog proves it from the facts.

Run it locallyInstall Ollama, run ollama pull llama3.1, and keep it running. The code talks to its OpenAI-compatible API at http://localhost:11434/v1, so the same program also works with vLLM, llama.cpp server or a cloud API by changing the URL, model name and adding an API key.
Part IV · Your path

Prolog learning roadmap

Tick items off as you go. Your progress is saved in this browser.

Beginner

Intermediate

Advanced

Part IV · Your path

Projects to build

Family treeDefine parent facts and derive relatives.
Sudoku solverSolve puzzles with CLP(FD).
GPU advisorAn expert system that recommends hardware.
Reference

Prolog cheat sheet

TaskSyntax
Factgpu(h100, 80).
Rulebig(G) :- gpu(G, V), V > 100.
Query?- gpu(X, 80).
ArithmeticX is 2 + 3
All answersfindall(X, gpu(X, _), L)
List[H|T]
Reference

Common mistakes

  • Every clause ends with a period.
  • = unifies terms; use is for arithmetic and =:= to compare numbers.
  • Left-recursive rules can loop forever; put the base case first.
Reference

Where to go next

On TensorCore.si: Lisp volume, Python volume.

Keyboard: [ previous language · ] next language · / search the library