Facts: what the program knows
The shape of a Prolog program: facts you state, the starting rule the page runs, and printing answers with write and nl.
Statements, not steps
Most languages make you write a sequence of instructions. Prolog asks for something else: you write down statements that are true, and the engine searches for answers that fit. A list of facts is already a program.
A fact looks like book(dune, herbert). — a name, then arguments in brackets, then a full stop. The name is lowercase and the arguments are lowercase words or numbers. Nothing here computes; the fact simply is.
A fact has three parts: a name, a bracketed list of arguments, and a full stop. The name is the predicate, and the count of arguments is its arity. A fact with no arguments is still a fact: raining. has arity zero and is written without brackets. Quoted atoms let a value contain a space, so city('New York'). is one argument, not two.
Starting the program, and printing
The page needs to know which goal to run, so every example in this course ends with the line :- initialization(main). It names the rule called main, and without it a program prints nothing at all.
Inside main you print with write, which takes one value, and with nl, which writes a line break. A word written in quotes loses the quotes on the way out, and a bare word never had any, so both print the same two letters or the same word.
How Prolog finds an answer
When you ask a question, Prolog does not run a list of steps. It tries to match the question against the facts and rules it has, one at a time, and it keeps every match as a possible answer. If a later goal fails, it goes back to the last choice and tries the next one — that behaviour is called backtracking.
This is why a fact file can answer a question the author never wrote down. book(dune, herbert). also answers "who wrote dune?" and "which books did herbert write?" because the same fact can be read in either direction.
The engine reads clauses from top to bottom and tries each one in turn. When a fact matches, it keeps the bindings and moves to the next goal; when a later goal fails, it returns to the most recent fact that still has untried alternatives. That order is fixed by the file, not by the query, so moving a fact changes the order of the answers even when it does not change the set.
The case of a name matters. A word starting with a lowercase letter is an atom — a fixed value such as dune. A word starting with an uppercase letter is a variable, and it matches anything. Writing Book where you meant book changes the meaning completely, and a missing full stop makes the next fact part of the same sentence.
Facts, and the goal that prints
% Facts end with a full stop.
city(lisbon).
city(oslo).
main :-
city(lisbon),
write('lisbon is a city'), nl.
:- initialization(main).Arity, and where rules begin
A fact with two arguments and a fact with three are different predicates: the number of arguments is the predicate’s arity. book/2 and book/3 can coexist without confusion, which is why error messages name the predicate and its arity together.
Facts describe what is true; rules describe what follows from it. The lookup is the same either way: match the head, satisfy the body, and backtrack for more answers. The next chapters add rules, but the engine you are watching is already doing the work.
Arity is part of the name for every practical purpose. book/2 and book/3 are separate predicates, and a call with the wrong number of arguments raises an error that names both the predicate and the arity it expected. That is why an error message such as book/3 tells you exactly which definition the engine was looking for.
What goes wrong
Three mistakes account for most empty outputs. A missing full stop joins two facts into one malformed clause. An uppercase name where you meant an atom turns a fixed value into a variable, so book(Dune) asks about any Dune rather than the atom dune. And printing a variable that was never bound shows an internal name such as _1234, which is the engine saying it has nothing to print.
Try these next
- Add a
director/2predicate and print one director and film. - Ask for the same fact with the arguments in the other order by changing the goal, not the fact.
- Write a fact with a number argument, such as
year(dune, 1965)., and print it.
Three facts, two answers
Run it and read the two lines. Then add a fourth book and print it the same way.
Ask the same facts a different question
Run it and read both lines. Then add a second parent fact and a goal that prints that parent and child.
Arguments are known by their position, so book(dune, herbert) means the first argument is the book and the second is the author. That convention is yours to keep, and the next chapter shows why it matters.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What does the line :- initialization(main). do?
