Thursday, October 09, 2025

What is Prolog?

After dedicating several blogs to the implementation of a subset of pure Prolog - with more to come - I thought it prudent to give an explanation as to what Prolog is. The words that follow are not mine but those of Patrick H. Winston as quoted in Ivan Bratko's "Prolog programming for artificial intelligence" (1986).

The best way to learn about goal-oriented programming is to read and write goal-oriented programs in Prolog, for goal-oriented programming is what Prolog is all about.

In broader terms, the evolution of computer languages is an evolution away from low-level languages, in which the programmer specifies how something is to be done [otherwise known as imperative languages - NBN], toward high-level languages, in which the programmer specifies simply what is to be done [declarative languages; Prolog and SQL are examples of such languages - NBN]. With the development of Fortran, for example, programmers were no longer forced to speak to the computer in the procrustian low-level language of addresses and registers. Instead, Fortran programmers could speak in their own language, or nearly so, using a notation that made only moderate concessions to the one-dimensional, 80-column world.

The chapters of this book [Bratko] clearly illustrate the difference between how-type and what-type thinking. In the first chapter, for example, the difference is illustrated through problems dealing with family relations. The Prolog programmer straightforwardly describes the grandfather concept in explicit, natural terms: a grandfather is a father of a parent. Here is the Prolog notation:
grandfather(X, Z) :- father( X, Y), parent( Y, Z).
Once Prolog knows what a grandfather is, it is easy to ask a question: who are Patrick's grandfathers, for example. Here again is the Prolog notation, along with a typical answer:
?- grandfather( X, patrick).
X = james;
X = carl

It is Prolog's job to figure out how to solve the problem by combing through a database of known father and parent relations. The programmer specifies only what is known and what question is to be solved. The programmer is more concerned with knowledge and less concerned with algorithms that exploit the knowledge.

As the hierarchy of families is well-known to everybody, almost all Prolog books begin with the same type of database. For example, the database that I have been using to test my interpreter is as follows

parent (noam, netta). parent (noam, nir). parent (sarit, netta). parent (sarit, nir). male (noam). male (nir). female (sarit). female (netta). female (shaked). female (lior). female (romi). parent (netta, shaked). parent (netta, lior). parent (nir, romi). father (X, Y):- male(X), parent(X, Y). mother (X, Y):- female(X), parent(X, Y). grandparent (X, Y):- parent(X, Z), parent(Z, Y).
As a result, I can ask who is a mother (and who are her children), who is a father, and who is a grandparent, receiving answers (solutions) even though these answers are not contained within the database. This is what I call the deceptive simplicity of Prolog. If this doesn't interest you, then don't read on.

I was thinking last night in bed (an activity that normally would prevent me from falling asleep) how to represent the 'sister' relationship. Note that technically there are two different relationships here: Netta is Nir's sister (singular), but Netta and Nir are not sisters (plural). On the other hand, Shaked is Lior's sister, and Shaked and Lior are sisters. At the moment, I am going to model the simpler 'sister' relationship. as follows
sister (X, Y):- female (X), parent (Z, X), parent (Z, Y).
In English, this says that one person is the sister of another if the first person is female and the two people share a parent.

Running the query ?- sister (X, Y). in the interpreter reveals a few problems, one of which I knew about in advance, and one unexpected problem which is a bug.  The unexpected bug is that the interpreter also shows the value of the intermediate Z variable; this should not happen. This is easily fixed: CP solved the problem with what I would call a hack, by storing any variables in the original query in a list, then when printing solutions, this list is checked to see which variables should be displayed.

I'll discuss the sister query in a separate post.



This day in blog history:

Blog #Date TitleTags
20609/10/2009Firebird triggers and autoincrementsProgramming, Delphi, Firebird
76309/10/2014Literature review: getting down to businessDBA
134409/10/2020Converting a Delphi 7 semi-unicode program to Delphi 10Programming, Delphi, Unicode
153409/10/2022DBA updateDBA, Non-fiction books

No comments: