Programming Languages (CSC-302 98S)
Outline of Class 33: Logic Programming in Prolog
Held: Wednesday, April 22, 1998
- The second exam is this Friday. It will cover general functional
programming issues, as well as some details in Haskell and Scheme.
I've prepared a short review
sheet so that you can have a sense of what will be on the exam.
Feel free to ask me questions about the exam in class today. Note
also that I'm willing to discuss rescheduling for those of you who
have too many other pressing commitments.
- A number of you handed in assignment five very late. Those assignments
are at the bottom of my "to do" pile and probably won't be graded for
- A few of you have asked for a "redo assignment" for assignment five.
I'll try to have one ready for Friday.
- I encourage those of you who haven't read the Kane and Krukowski
reports to do so. Learn about what people are recommending for
- On Friday, May 1, the department will be hosting a picnic at Merrill
park. Sign up to have fun with the majors, nonmajors, faculty, and
families. It's gotta be more fun than the MathLAN, right?
- Prolog can be found in
can be found at
- How might we use the predicate logic as a programming language?
We could state "theorems" and ask the system to prove the theorems
based on the rules of predicate logic and the definitions contained
within our program. In effect, we state our theorem as a question and
ask the program to answer it.
- For example: "Is Socrates mortal?" "Yes, because Socrates is
a person and all people are mortal."
- Similarly: "Are there any mortals?" "Yes, Socrates is a mortal
because Socrates is a person and all people are mortal."
- Similarly: "Is Socrates immortal?" "No, because Socrates is
mortal (see above) and no mortal is immortal."
- And "Is Lou Reed influential?" "Yes, because Lou Reed was a
member of the Velvet Underground and R.E.M. were influenced by the
- How might we implement such a language? Well, there are two
aspects, depending on the type of question that is being asked.
- To prove a theorem about an atom. In this case, we might "plug" the
atom in to the right hand side and then attempt to prove the right
- To prove a theorem about a variable, we may need to "guess" instantiations
and plug in.
- Note that the first quickly becomes the second. For example, in
proving that Lou Reed is influential, we need to identify a band that
Lou Reed was/is a member of. Then, we need to determine whether that
band is influential.
- It turns out that some aspects of such proofs are extremely difficult.
In particular, it may be impossible to prove a negation.
- To simplify matters, we may want to write a disjunction of
Horn clauses: clauses that define predicates in which consist
of only an and of assertions (i.e., no nots, the only ors are
used around our horn clauses).
- In such a system, we have a simpler nondeterministic proof strategy:
pick a rule that defines a predicate and attempt to prove each component
of the right hand side.
- Of course, that leads to the question of how to deal with the nondeterminism.
We'll return to that question later.
- Prolog was developed in the early 1970's to demonstrate that it is
possible to "program" in predicate logic. The paper that introduced
prolog was titled something like "Logic + Control = Program".
- When people speak of "logic programming" they often mean
- This can lead to some interesting misunderstandings. If have friends
who do "equational logic programming", programming based on the logic
of equations. However, many people think that they do "Prolog + equations".
- Prolog includes some nonlogical components (we'll discuss some of them),
some of which are there for the sake of efficiency.
- Many Prolog programmers take advantage of knowledge of these nonlogical
- An interaction with a Prolog system consists of
- Specifications of basic facts about objects and relationships
("The Velvet Underground was an influential band.", "Maureen Tucker was
a member of the Velvet Underground")
- Specifications of rules about objects and relationships
("All members of influential bands are influential.")
- Ask questions about objects and relationships
("Is Lou Reed influential?" "Is Barry Manilow influential?" "Are there
any influential musicians?")
- As this suggests, Prolog is particularly good at working with so-called
"atomic" or "symbolic" values. That is, values whose meaning is determined
by the program.
- Basic syntax:
- atoms, predicates, and functions begin with lowercase letters. For
- variables begin with uppercase letters or underscore. For example,
- the arguments to a predicate are parenthesized and separated by commas.
- a period indicates the end of a fact or rule.
- lists are surrounded by brackets; items in a list are separated by
commas; the vertical bar acts like cons (more or less).
 -- the empty list
[a,b,c] -- a list of three elements
[a|X] -- a list whose first element is a and whose
remainder is the list X.
- [a,b|X] -- a list whose first two elements are a and b and
whose remainder is the list X.
- Prolog predicate definitions have the form
P :- Q1,Q2,...,Qn.
where the P and Q's are all predicate applications.
- For example,
influential(X) :- influencedBy(X,Y).
- The meaning of the general form is "for (all the variables in P), if
there exist values for (all the other variables in the Q's) such that
all the Q's hold, then P holds.
- Basic facts (e.g., coolDude(louReed).) do not require the :-.
- A Prolog program is a collection of definitions. Input is a question,
such as "does this predicate hold on these values?"
or "for what values does this predicate hold?"
- Prolog is often used for databases as the basic facts are effectively
database entries and the predicate definitions are ways to reason with
the basic entries.
- How might we write a program that describes some information about modern
- First, we might want to choose some appropriate predicates. The one's
I've come up with are:
influential(Group_or_Musician): is a group or musician
Beta. Note that the meaning and ordering are determined
solely by my description (and, later, by definitions).
Musician is a member
fame (perhaps all do, but we'll come up with some rules that may
help decide when).
- We'll develop some of our own rules, but here are some to start with.
- A group or musician is influential if they influenced someone.
influential(G_or_M) :- influenced(G_or_M, Someone).
- A musician is influential if he or she belongs to an influential group.
influential(Musician) :- memberOf(Musician,Group), influential(Group).
- Note that I might also have defined this as:
influential(Musician) :- influential(Group), memberOf(Musician,Group).
- This makes no difference logically, but may make some difference
relative to Prolog's solution strategy. The first is probably better.
- When does someone deserve fame? Perhaps when they influenced a
group that had a gold record. (See, logic is hard :-).
deservesFame(M_or_G) :- influenced(M_or_G, Group), gold(Group, Record).
- A group deserves fame if they influenced someone who deserves fame.
deservesFame(M_or_G) :- influenced(M_or_G, Group), deservesFame(Group).
- Again, ordering may make a difference in efficiency
(both ordering of rules and ordering of right-hand-sides).
- The remaining predicates may be defined by "base facts". Here
are a few.
- We can now ask questions.
?- memberOf(X, velvet_underground).
- Note that when I wanted other answers, I typed a semicolon. This is
somewhat equivalent to "what else can you prove?".
- Note also that some of our predicates may be oddly defined. For example,
our rules don't allow us to prove that members of groups that deserve fame
also deserve fame. We could add rules for
we could add a recursive rule for influenced.
- Note also that careless use of our rules can lead to false conclusions.
For example, while the Velvet Underground were clearly influential,
Willie "Loco" Alexander is far from influential.