# Philosophy, Computing, and Artificial Intelligence

PHI 319. The Computer Language Prolog. Thinking as Computation
Chapter 3 (41-61), Chapter 4 (63-81), Appendix B-C (279-288)
Prolog programs

## Prolog ("PROgrammation en LOGique")

Prolog is a computer language based on logic programming.

For a straightforward and helpful general tutorial on Prolog, see Learn Prolog Now!

In Prolog, programs are definite programs. The way Prolog works will be partly familiar to you on the basis of the last lecture. On the left below, there are two examples of clauses in the propositional calculus. On the right, there are the corresponding ways they are written in Prolog.

```
a               |               a.                      (fact)
|
a ∨ ¬b ∨ ¬c     |               a :- b, c.              (rule) (head :- body.)

```

The following set of equivalences helps to clarify the correspondence:

```
a ∨ ¬b ∨ ¬c      iff           a ∨ ¬(b ∧ c)
(b ∧ c) → a
a ← (b ∧ c)
a :- b, c.

```

Queries are understood as negative clauses. The following is a negative clause:

¬a ∨ ¬b ∨ ¬c

This negative clause is equivalent to

¬(a ∧ b ∧ c)

In Prolog, this negative clause corresponds to a query and is written as

?- a, b, c.

The evaluation step corresponds to an application of the deduction rule called resolution. Given two clauses presented in disjunctive format, resolution eliminates a pair of complementary literals and constructs a new clause (the resolvent) from the literals that remain. Two literals are complimentary if and only if one is the negation of the other. The basic evaluation step of Prolog is the backward chaining process in logic programming.

```
In Prolog                               In logic

query           ?-a,d,e.                ¬a ∨ ¬d  ∨ ¬e
program clause  a:-b,c.                  a ∨ ¬b ∨ ¬c
derived query   ?-b,c,d,e.              ¬b ∨ ¬c  ∨ ¬d ∨ ¬e

```

The logical relationship is

{negative clause, program clause} ⊢ negative clause

For explanation of the four database manipulation commands in Prolog, see Database Manipulation in the tutorial.

This is not a course in computer programming, but you should play around some with Prolog. Maybe the easiest way is to use the online version in which you can cut and paste programs. Another way is to install it on your computer. This is what I have done.

Here is a screen shot of my terminal. I issue the command "swipl" to start Prolog. At that point, Prolog waits for a goal. (The "?-" its way of asking for a goal.) I respond to this request by asserting a fact (that "Socrates is a man" ) and a rule (that "Everything that is a man is mortal"). Prolog puts this fact and rule into the KB. (That is what the response "true" indicates.) Now the KB is

man(socrates).
mortal(X):-man(X).

Against this KB, I ask "whether something is mortal" and "whether something is a man." Given the KB, Prolog should tell me that socrates is mortal and a man. Prolog treats any term that begins with an uppercase letter (or the underscore) as a variable. So in the rule " mortal(X):-man(X)," Prolog treats "X" as a variable.

Because the variable was in the supplied goals ("mortal(X)" and "man(X)") Prolog identifies the constant to which the variable is bound in the computation ("X = socrates").
That is what happens. ## The "Family" Example (Thinking as Computation, 42)

I consult the file "family.pl" This file contains the program:

child(john,sue). child(john,sam).
child(jane,sue). child(jane,sam).
child(sue,george). child(sue,gina).

male(john). male(sam). male(george).
female(sue). female(jane). female(june).

parent(Y,X) :- child(X,Y).
father(Y,X) :- child(X,Y), male(Y).
opp_sex(X,Y) :- male(X), female(Y).
opp_sex(Y,X) :- male(X), female(Y).
grand_father(X,Z) :- father(X,Y), parent(Y,Z)

I pose a few queries. I ask whether sue is the father of anyone. I ask whether sam is the father of any female. I ask whether sam is the child of anyone. Prolog can disregard the current binding and look for another. This is what happens when I type ";" (which is logically equivalent to "or"). The first reply is john. I use the ";" to ask whether sam is the child of anyone else. I ask whether president_crow is male. To test your understanding, here is a question about the fourth query in the family example.

President Crow (of ASU) is male, but Prolog responds with "false."

What is going on here?

To answer, explain what "false" means in the reply. It does not mean that the proposition expressed by "President Crow is male" is false. It means that something else is false. What is it?

## The Pulp Fiction Example

I consult the file (I created called) "pulpfiction.pl" This file contains the program. I list the two predicates in the program. I pose a few queries. I halt Prolog. ## The "Blocks" Program

Here is the blocks program from the previous lecture:

on(b1,b2).
on(b3,b4).
on(b4,b5).
on(b5,b6).

above(X,Y) :- on(X,Y).
above(X,Y) :- on(X,Z), above(Z,Y).

This program consists in four facts (about which block is on top of which block) and two rules (that define the "above" relation). Corresponding to the facts and rules is the following model of the world (use your imagination to see blocks on top of one another):

```
b3
b4
b1     b5
b2     b6

```

Here is the trace for "above(b3, b5)." creep causes the debugger to single-step. leap causes it to resume running the program. You probably thought computer scientists have no sense of humor. The query "above(b3, b5)" unifies with the first rule. The derived query is "on(b3, b5)." This derived query fails. Now we have to try the query with the second rule.

The second rule now takes the form

above(b3, b5) :- on(b3, _2156), above(_2156, b5).

"_2156" is a variable. It is bound to "b4." The derived query list is "on(b3, b4), above(b4, b5)." These queries succeed, so the original query succeeds.

Here is the trace for "above(b3,b3)." The query "above(b3,b3)" is unified with the first rule "above(X,Y) :- on(X,Y)." This fails because "on(b3, b3)" fails. So the program tries to unify the query "above(b3,b3)" with the second rule "above(X,Y) :- on(X,Z), above(Z,Y)." This rule takes the form

"above(b3, b3) :- on(b3, _2156), above(_2156, b3)."

"_2156" is bound to "b4." The derived query list is "on(b3, b4), above(b4, b3)." The first query succeeds, but the second fails against the first rule because "on(b4, b3)" fails.

So now the program tries to unify "above(b4, b3)" with the second rule. This time the variable is bound to "b5." The derived query list is "on(b4, b5), above(b5, b3)." The first query in this list succeeds, but the second fails against the first rule because "on(b5, b3)" fails.

So now the program tries to unify "above(b5, b3)" with the second rule. This time the variable is bound to "b6." Now the derived query list is "on(b5, b6), above(b6, b3)." The first query in this list succeeds, but the second fails against the first rule because "on(b6, b3)" fails.

Now there is no constant to bind to the variable. So "above(b6, b3)" fails, "above(b5, b3)" fails, and "above(b4, b3)" fails. Hence the original query "above(b3, b3)" fails.

## Some Explanation of Lists in Prolog

We will uses lists in Prolog later in the course when we come to natural language processing (NLP). Lists are a finite sequence of elements. They are specified in Prolog by separating the elements by commas and enclosing them in square brackets. The empty list is a list.

A non-empty list has a head and a tail. The head is the first element. The tail is the rest. Prolog has a built-in operator | to decompose a list into its head and tail. ## An Adventure Game Written in Prolog

Here is the game. I found it on the internet. I have not played it enough to know how well it works. You might find it interesting to look at the program to see why it does what it does. ## What we have Accomplished in this Lecture

We have become familiar with some of the basics of programming in Prolog and how Prolog incorporates some of the principles of logic programming.