TK2313 Artificial Intelligence · Logic Programming
PROLOG
Introduction & Syntax Familiarization
Press → or Space to begin · N speaker notes · O overview
Welcome. Today: read and write basic Prolog and run it in SWI-Prolog. Open SWI-Prolog on the lecturer PC now and keep it beside this deck. Every grey code box has a Copy button.
Today · 60 minutes
The roadmap
01 · 10 min Why Prolog? Declarative thinking · SWI-Prolog
02 · 10 min Syntax Atoms · Variables · Terms
03 · 15 min Facts, Queries, Rules AND · OR · NOT
04 · 15 min Under the hood Unification · Backtracking · Recursion · Lists
05 · 10 min Debug & Practise Errors · trace · Challenge
🎯 Goal: read, write and run simple Prolog programs, ready for the Lab.
Quick overview. Tell students they will type along in the lab right after this.
Part 01
Why Prolog?
Describe what is true, not how to compute it.
01
Two ways to think
Imperative vs Declarative
Python · HOW
parents = [("ali","aminah"), ("aminah","danial")]
for (p, c) in parents:
for (p2, c2) in parents:
if c == p2:
print(p, "is grandparent of", c2)
You write the loops and the order .
Prolog · WHAT
parent(ali, aminah).
parent(aminah, danial).
grandparent(G, C) :- parent(G, P), parent(P, C).
grandparent(G, C). G = ali,\nC = danial.
You state facts & logic . Prolog searches for answers.
Same problem, two mindsets. In Prolog there is no loop and no print. The search is built into the language. Ask: "Which one reads closer to English?"
The whole idea in one picture
Knowledge + Question → Proof
KNOWLEDGE BASE
your program (.pl file)
parent(ali, aminah).
male(ali).
father(F,C) :- ...
QUERY
?- father(X, aminah).
INFERENCE
ENGINE
unify · search · backtrack
ANSWERS
X = ali.
or true. / false.
Prolog = PROgramming in LOGic. You give it a knowledge base and a question. The engine tries to prove the question from the knowledge. If it can, it answers with the variable values that made it true.
Since 1972 · Colmerauer & Kowalski
Where does Prolog live?
🩺
Expert systems rules → diagnosis (our Paddy lab!)
🗣️
Language parsing & grammars (NLP in IBM Watson)
🧩
Puzzles & planning scheduling, Sudoku, constraints
🧠
Knowledge rep. ontologies, logic & reasoning
Prolog is the hands-on companion to our Knowledge Representation & Logic lectures: facts, rules, inference.
Keep this short. Link it to the course: KR, logic, reasoning, and the expert-system lab later on.
Live demo · open SWI-Prolog
Meet the ?- prompt
1 Open SWI-Prolog (swipl-win, or swipl in a terminal)
2 The prompt ?- means“ask me something”
3 Every query ends with a full stop . then Enter
X = hello. X = hello.
write('Hello, Prolog!'), nl. @Hello, Prolog!\ntrue.
X is 6 * 7. X = 42.
Paste each query with the Copy button. Point out: the full stop is mandatory; without it SWI waits on a new line with "|". Type the missing "." to finish.
Rule #1 of working in Prolog
Facts go in a file . Questions go at ?-
📄 program · .pl file
Facts & rules: the knowledge . Loaded with consult .
?- query · console
Questions about the knowledge. Prolog answers true / false / values .
parent(ali, aminah). !ERROR: Unknown procedure: parent/2 (DWIM could not correct goal)
☝ Typing a fact at ?- does not add it. Prolog treats it as a question about a program that isn't loaded yet.
This is the number-one beginner confusion. Demo it live in a fresh SWI-Prolog with nothing loaded: paste the query and show the error.
Two ways to load code
Getting code into Prolog
A · file (recommended)
1 Save the demo file as tk2313_prolog_intro.pl
2 Load it (or File ▸ Consult… ):
consult('C:/Users/me/Desktop/tk2313_prolog_intro.pl'). true.
Use forward slashes / in Windows paths. After editing the file, reload with make.
⤓ Download demo .pl ⧉ Copy whole file
B · quick paste
[user]. @|: ← paste clauses here
Paste facts & rules, then end input withCtrl + D (Windows console: Ctrl +Z , Enter )
Great for tiny demos, but the code is lost when you quit. Use a file for real work.
Download the demo file now and consult it. If the path is wrong you get "source_sink ... does not exist". Then check the path, or use File ▸ Consult in swipl-win. Tip: ?- pwd. shows the working folder; ?- cd('C:/path'). changes it, then ?- [tk2313_prolog_intro]. works.
Part 02
The building blocks
Everything in Prolog is a term .
02
One data type to rule them all
Everything is a term
term
constant
variable
X Food _
compound
parent(ali, aminah)
[1, 2, 3]
atom
ali 'Kuala Lumpur'
number
42 3.14 -7
Reveal the tree branch by branch. Constants are fixed values; variables are unknowns; compound terms are structures built from a name plus arguments.
Constants · names of things
Atoms start lowercase
a lowercase letter first: ali nasi_lemak tk2313
' anything in single quotes : 'Kuala Lumpur' 'Ali'
+ symbol sequences: + =.. []
❌ Ali is not an atom, it is a variable ! ❌ nasi lemak has a space. Use nasi_lemak .
atom(ali). true.
atom('Kuala Lumpur'). true.
atom(Ali). false.
Let students predict the third one before revealing: Ali with a capital A is a variable (unbound), so atom(Ali) is false.
Unknowns to be found
Variables start Uppercase or _
_ Anonymous _ means “I don't care what it is”
= A variable gets a value once : no X = X + 1 like in Python
↻ Same name in one clause = same value
X = 5, Y = X. X = Y, Y = 5.
X = 5, X = 6. false.
parent(ali, _). true ;\ntrue.
Requires the demo file to be loaded for the last query. X = 5, X = 6 is false because X is already 5: variables are not boxes you overwrite. The last query answers "does ali have any child?" without naming it; it is true twice (aminah, badrul).
Structures
Compound terms : functor + arguments
parent ( ali , aminah ) .
functor (name)
arguments
parent/2 name / arity (no. of args)
full stop
parent/2 and parent/3 are different predicates. No space before ( !
Introduce the name/arity notation now: SWI error messages always use it (e.g. Unknown procedure: parent/2).
Quick check · shout it out!
Atom, variable, number or invalid?
2nd_place
invalid: digit first
Point at each token, let the class answer, then reveal. Common traps: quoted 'Siti' IS an atom; _x is a variable.
Part 03
Facts, Queries & Rules
Our running example: one Malaysian family 👨👩👧👦
03
Section divider. Make sure the demo file is consulted before continuing.
Facts · things that are simply true
Facts: relation(object, …).
parent(ali, aminah).
parent(ali, badrul).
parent(siti, aminah).
parent(siti, badrul).
parent(aminah, danial).
parent(badrul, farah).
parent(danial, hana).
male(ali). female(siti).
male(badrul). female(aminah).
male(danial). female(farah).
female(hana).
ali 72
siti 68
aminah 45
badrul 41
danial 24
farah 16
hana 2
These facts are already in the demo file (with ages via age/2 and food via likes/2). Note the convention: parent(Parent, Child). The order of arguments is YOUR decision; keep it consistent.
Queries · ask a question
Yes/no questions → true / false
parent(ali, aminah). true ;\nfalse.
parent(aminah, ali). false.
male(hana). false.
Closed world: if Prolog can't prove it from the program, the answer is false . It does not mean “impossible” , only “not known” .
Why true ; then false ? Prolog found it but still had another parent(ali, …) fact to try. Press ; to check it: no more, so false . Press Enter to stop instead.
Run the first query: SWI prints "true" and waits. Press ; to show the false. Explain the choice point. It is normal, not an error.
Queries · let Prolog find values
Variables ask “who?” / “what?”
parent(ali, X). X = aminah ;\nX = badrul.
parent(X, danial). X = aminah.
likes(Who, nasi_lemak). Who = aminah ;\nWho = danial.
Translate: “Is there an X such that ali is a parent of X?”
Emphasise reading a query aloud as a question with "there exists". Let the students press ; themselves on the lab PCs.
Comma , = AND
Combine goals with ,
parent(ali, X), female(X). X = aminah ;\nfalse.
parent(siti, P), parent(P, G). P = aminah,\nG = danial ;\nP = badrul,\nG = farah.
The same variable links the goals: the X found in goal 1 must also pass goal 2.
Query 2 = “grandchildren of siti” . We'll turn it into a reusable rule next.
Read query 1 aloud: "a child X of ali, AND X is female". The trailing false comes from trying badrul (male) after the first answer.
Rules · knowledge that depends on other knowledge
Anatomy of a rule
father(F, C) :- parent(F, C) , male(F) .
BODY conditions, joined by , = AND
🗣 “F is the father of C if F is a parent of C and F is male.”
A fact is a rule with an empty body (always true). Facts + rules = Horn clauses: head :- body.
Live demo · rules in the demo file
Family rules
father(F, C) :- parent(F, C), male(F).
mother(M, C) :- parent(M, C), female(M).
grandparent(G, C) :- parent(G, P), parent(P, C).
sibling(X, Y) :- parent(P, X), parent(P, Y), X \= Y.
🤔 Why does badrul appear twice ?Aminah and Badrul share two parents, so it is proved once via ali and once via siti.
father(F, aminah). F = ali ;\nfalse.
grandparent(ali, Who). Who = danial ;\nWho = farah.
sibling(aminah, S). S = badrul ;\nS = badrul.
X \= Y means "X does not unify with Y", so nobody is their own sibling. Let students try removing it (in the file, then make.) to see aminah become her own sibling. The duplicate answer is a great discussion: Prolog finds every PROOF, not every unique value.
Two ways to say OR
OR = ; or several clauses
guardian(G, C) :- parent(G, C).
guardian(G, C) :- grandparent(G, C).
guardian(ali, C). C = aminah ;\nC = badrul ;\nC = danial ;\nC = farah.
Same meaning, one clause:guardian(G,C) :- parent(G,C) ; grandparent(G,C).
parent(ali, X) ; parent(danial, X). X = aminah ;\nX = badrul ;\nX = hana.
Prefer separate clauses : easier to read and debug.
Prolog tries clauses top to bottom; each clause is an alternative way to prove the head.
NOT
\+ = “cannot be proved”
\+ male(siti). true.
\+ parent(hana, _). true.
Negation as failure: \+ G succeeds if G fails. Also written not(G) .
Query 2: “Hana has no children” is true because no fact says she has.
Keep brief; this is covered in more depth in the lab (Exercise 4).
Part 04
Under the hood
Unification · Arithmetic · Backtracking · Recursion · Lists
04
The heart of Prolog
Unification = makes two terms identical
term A
f / 2
X
b
term B
f / 2
a
Y
result
① functor ✓
② X = a
③ Y = b
f(X, b) = f(a, Y). X = a,\nY = b.
point(X, X) = point(1, 2). false.
likes(aminah, F) = likes(Who, nasi_lemak). F = nasi_lemak,\nWho = aminah.
Rules: same functor/arity, then unify arguments; a variable binds to anything; two different constants clash. Query 2 fails: X becomes 1, then must also be 2. Every query you have run so far used unification to match facts!
Most common confusion
Four kinds of “equal ”
operator meaning example result
=unify (pattern match) X = 1 + 2X = 1+2 no maths!
isevaluate right side X is 1 + 2X = 3
=:=numbers equal? 2 + 1 =:= 3true
==identical terms? 2 + 1 == 3false
X = 1 + 2. X = 1+2.
X is 1 + 2. X = 3.
Run both queries back to back. 1+2 is just a compound term +(1,2) until is evaluates it.
Numbers
Arithmetic & comparison
+ - * / // mod **
< > =< >= =:= =\=
⚠ It's =< , not <= (that looks like an arrow ⇐ in Prolog).
adult(X) :- age(X, A), A >= 18.
teen(X) :- age(X, A), A >= 13, A =< 19.
older(X, Y) :- age(X, A), age(Y, B), A > B.
X is 7 / 2, Y is 7 // 2, Z is 7 mod 2. X = 3.5,\nY = 3,\nZ = 1.
teen(X). X = farah ;\nfalse.
age(X, A), A < 20. X = farah,\nA = 16 ;\nX = hana,\nA = 2.
// is integer division, mod is remainder. Comparisons need both sides to be numbers (bound), otherwise: "Arguments are not sufficiently instantiated".
How Prolog searches
Backtracking : depth-first, left-to-right
?- parent(ali, X), female(X).
① parent(ali, aminah) EXIT · X = aminah
② female(aminah) ✓
X = aminah ;
③ REDO → parent(ali, badrul)
④ female(badrul) ✗
no more → false.
Depth-first: finish one path completely before trying another.
Backtrack: on failure (or ; ), undo the last choice and try the next clause .
Walk through each node. Then in SWI run the query and press ; to match the tree. In the lab, PROLOG//LAB animates this tree automatically for any query.
Rules that use themselves
Recursion : ancestor
ancestor(A, D) :- parent(A, D). % base case
ancestor(A, D) :- parent(A, X), ancestor(X, D). % recursive
ancestor(ali, hana). true ;\nfalse.
ancestor(A, hana). A = danial ;\nA = ali ;\nA = siti ;\nA = aminah ;\nfalse.
ali
parent → recurse aminah
parent → recurse danial
base case ✓ hana
Always put the base case first , and make each recursive step move closer to it, or the recursion never stops.
Two clauses: either A is directly D's parent (base), or A is parent of some X who is an ancestor of D. Trace the chain ali → aminah → danial → hana.
The workhorse data structure
Lists: [Head | Tail]
HEAD TAIL (also a list)
[H|T] = [nasi_lemak, satay, laksa]. H = nasi_lemak,\nT = [satay, laksa].
member(satay, [nasi_lemak, satay]). true.
my_sum([10, 20, 30], S). S = 60.
my_sum([], 0).
my_sum([H|T], S) :- my_sum(T, S0), S is H + S0.
[] is the empty list. Recursion on lists: handle the head, recurse on the tail, stop at []. my_sum is in the demo file.
Cheat sheet
Handy built-ins
findall(C, parent(ali, C), Kids). Kids = [aminah, badrul].
append([1,2], [3], L). L = [1, 2, 3].
length([a,b,c], N). N = 3.
greet(aminah). @Selamat datang, aminah!\ntrue.
format("~w is ~w years old~n", [ali, 72]). @ali is 72 years old\ntrue.
listing(father). @father(F, C) :-\n@ parent(F, C),\n@ male(F).\ntrue.
findall collects ALL answers into a list (no need to press ;). listing shows the clauses Prolog has loaded, handy to check your file was consulted.
Part 05
Debug & practise
Read the error message. It tells you the line number.
05
Real SWI-Prolog messages
Top 5 beginner errors
1 · missing full stop
likes(ali, satay) ← no "."
ERROR: file.pl:1:18: Syntax error: Operator expected
✓ end every clause with . (it also swallows the next line!)
2 · uppercase predicate
?- Parent(ali, X).
ERROR: Syntax error: Operator expected
✓ predicate names are atoms → lowercase
3 · program not loaded / typo / wrong arity
ERROR: Unknown procedure: parent/2
✓ consult the file · check spelling · count the arguments
4 · singleton variable (warning)
bad(X, ali).
Warning: Singleton variables: [X]
✓ used only once? Probably a typo, or write _
5 · maths on an unknown
?- X is Y + 1.
ERROR: Arguments are not sufficiently instantiated
✓ give Y a value first: Y = 4, X is Y + 1.
And: typing a fact at ?- asks a question. It doesn't store anything.
All messages copied from SWI-Prolog 9. Optional live demo: add likes(ali, satay) without the dot to the file, run make., show the error, fix it.
See Prolog think
trace. step through a proof
trace, father(F, aminah). @ Call: (11) father(_16410, aminah) ? creep\n@ Call: (12) parent(_16410, aminah) ? creep\n@ Exit: (12) parent(ali, aminah) ? creep\n@ Call: (12) male(ali) ? creep\n@ Exit: (12) male(ali) ? creep\n@ Exit: (11) father(ali, aminah) ? creep\nF = ali .
Press Enter to creep step by step · notrace. to switch off · nodebug. to leave debug mode
Numbers like (11) and _16410 will differ on your machine. In swipl-win a graphical tracer may open instead (guitracer). Either is fine.
⏱ 5-minute challenge · in pairs
Your turn
2 Write uncle(U, C) : brother of a parent
3 Query: who likes the same food as aminah?
4 Bonus: count_kids(P, N) using findall + length
same_taste(aminah, Who). Who = danial.
count_kids(ali, N). N = 2.
grandmother(G, C) :- grandparent(G, C), female(G).
uncle(U, C) :- parent(P, C), sibling(U, P), male(U).
count_kids(P, N) :- findall(C, parent(P, C), Kids),
length(Kids, N).
uncle(U, danial). U = badrul ;\nU = badrul ;\nfalse.
Students add the rules to the end of the demo file, then run make. Reveal answers after ~5 minutes. Note uncle shows badrul twice, for the same two-parents reason as sibling.
Take-home cheat sheet
Prolog on one slide
fact.always true: parent(ali, aminah). %comment to end of line
h :- b.rule: h is true if b is true /* */block comment
, ; \+AND · OR · NOT [H|T]list head & tail
X _variable · don't-care isevaluate maths
=unify (match) =< >=compare numbers
; / Enter next answer / stop make.reload edited file
Students can photograph this slide.
Up next
PROLOG//LAB
Guided exercises · unification · resolution · cut · lists · expert system
?- questions(class).▌
⤓ Download demo .pl
Q&A, then share the first lab passcode.