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.
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.
Set up and run your first program
Install SWI-Prolog, the most popular free implementation.
sudo apt install swi-prolog
swipl hello.pl:- initialization(main).
main :-
Name = "Ada",
format("Hello, AI! Welcome to Prolog, ~w.~n", [Name]),
halt.[hello]. and type queries ending with a period.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.
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 answersRules
Rules define new facts from old ones. :- means "if" and a comma means "and".
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.Recursion and lists
Lists are written [H|T] (head and tail). Recursive rules process them; arithmetic uses is.
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.Backtracking and search
When a goal fails, Prolog goes back and tries another option. This makes puzzles and planning problems short to write.
% Assign 3 jobs to 3 GPUs, no GPU used twice
assign([], _, []).
assign([J|Js], Gpus, [J-G|Rest]) :-
select(G, Gpus, Left),
allowed(J, G),
assign(Js, Left, Rest).
allowed(train, h200).
allowed(train, h100).
allowed(infer, _).
allowed(embed, rtx5090).
% ?- assign([train, infer, embed], [h100, h200, rtx5090], Plan).Parsing with DCGs
Definite Clause Grammars turn grammar rules into parsers, one reason Prolog was popular for natural language processing.
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.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
Constraint solving
CLP(FD) solves a scheduling puzzle declaratively.
:- 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.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.
# 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.
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.Prolog learning roadmap
Tick items off as you go. Your progress is saved in this browser.
Beginner
Intermediate
Advanced
Projects to build
Prolog cheat sheet
| Task | Syntax |
|---|---|
| Fact | gpu(h100, 80). |
| Rule | big(G) :- gpu(G, V), V > 100. |
| Query | ?- gpu(X, 80). |
| Arithmetic | X is 2 + 3 |
| All answers | findall(X, gpu(X, _), L) |
| List | [H|T] |
Common mistakes
- Every clause ends with a period.
=unifies terms; useisfor arithmetic and=:=to compare numbers.- Left-recursive rules can loop forever; put the base case first.
Where to go next
- Learn Prolog Now! — free book
- SWI-Prolog — official
- The Power of Prolog — modern guide
On TensorCore.si: Lisp volume, Python volume.
Keyboard: [ previous language · ] next language · / search the library