3203. Introduction to Artificial Intelligence

Prolog (1)

### 1. Prolog overview

Prolog is a logic programming language. The name itself, Prolog, or PROLOG, is short for "PROgramming in LOGic". The first Prolog implementation was the work of Colmerauer in 1970, designed to facilitate natural language processing.

Logic programming is a type of declarative programming. Different from procedural programming languages, such as C/C++ and Java, the focus of declarative programming is to describe a situation (a set of knowledge), not to describe a solution (a sequence of instructions). Especially, logic programming uses a language that is similar to logic, writes a program as a list of facts and rules, and treats the execution of a program as an inference process, from given facts and rules to the desired goal.

### 2. Facts and rules

A Prolog program consists of a sequence of facts and rules.

In the simplest situation, a fact is a predicate name followed by an argument list and a dot sign, ".". It represents a relation among the arguments, or a property of a (single) argument.

Prolog uses the convention that a constant is an identifier starting with a lower-case letter, while a variable is an identifier starting with a upper-case letter. A constant stands for a specific entity, and different constants stand for different entities. On the other hand, a variable can stand for any entity, and different variables can stand for the same entity. The predicate name must be a constant, while each argument can either be a constant or a variable. The scope of a variable is a rule or fact, while the scope of a constant is the whole program.

For example, "George is funny" can be represented as a Prolog fact:

`    funny(george).`
"George likes swimming" can be represented as:
`    likes(george, swimming).`
Tricky points:
• "likes(george, swimming)." is different from "likes(swimming, george)."
• "likes(george, swimming)." is different from "likes(George, swimming)."
• "likes(X, swimming)." is the same as "likes(George, swimming)."
• don't forget the ending dot.
A rule can be seen as a "conditional fact". "Susie likes swimming if George likes swimming" is represented as a Prolog rule:
`    likes(susie, swimming) :- likes(george, swimming).`
Tricky points:
• The two characters ":-" represent "if", with the condition on the right-hand side.
• "likes(george, swimming) :- likes(susie, swimming)." is different from "likes(susie, swimming) :- likes(george, swimming)."
• "likes(george, swimming) :- likes(susie, swimming)." is different from "likes(george, Swimming) :- likes(susie, Swimming)."
• "likes(george, X) :- likes(susie, X)." is the same as "likes(george, Swimming) :- likes(susie, Swimming)."
A rule can have multiple (co-existing) conditions, separated by ",". For example, "Mary likes whatever Susie and George like" is represented as:
`    likes(mary, X) :- likes(susie, X), likes(george, X).`

### 3. Programs and queries

A Prolog program consists of a list of facts and rules and the source code has extension ".pl", such as the file "likes.pl":
```likes(george, swimming).
likes(susie, swimming) :- likes(george, swimming).
likes(mary, X) :- likes(susie, X), likes(george, X).
```
With SWI-Prolog installed, a Prolog program can be executed by double click the file. Then the program is loaded into the system's "database", and can be used to answer queries, or to achieve goals.

Prolog is an interactive language. The interpreter accepts queries at the prompt "?-", and a query is just like a fact, except that its truth will be judged by the program. To do that, the Prolog interpreter tries to "match" the query with sentences in the program one by one (from top to bottom), and answers "true" when a match is found, otherwise answer "false".

For example, after the above program is loaded, we will have:

```?- likes(george, swimming).
true.

?- likes(jack, biking).
false.
```
Please note that in Prolog there is no "I don't know", and "false" is the answer as far as "true" cannot be obtained. This is called "closed-world assumption".

When a query meets a rule, and the "head" (the conclusion part, or the left-hand side) of the rule matches the query, then the interpreter treats the conditions of the rule as derived sub-queries, and recursively check for them one by one (from left to right). If the answer for them are all "true", the original query gets an "true", otherwise it gets a "false".

```?- likes(susie, swimming).
true.
```
When there are variables in the sentences to be matched, the interpreter tries to "unify" them, by substituting a variable by a constant (or another variable). If a query contains variable(s) and the unifications are successful, then the relevant substitutions are reported as the answer (and the "true" is no longer explicitly reported).
```?- likes(susie, X).
X = swimming.

?- likes(X, swimming).
X = george
```
If the "enter" key is typed, the query is finished, and the next prompt is displayed. For queries with multiple answers, type a semicolen ";" after an answer will make the interpreter continues to look for the next answer.
```?- likes(X, swimming).
X = george ;
X = susie ;
X = mary.
```
In the current SWI-Prolog implementation, all predicate names must be defined in the program, though arguments in the query can be novel. For example,
```?- likes(amy, running).
false.

?- hates(amy, running).
ERROR: toplevel: Undefined procedure: hate/2 (DWIM could not correct goal)
```
Though in same other implementations, the second query also gets "false" as the answer.

A program can have any number of predicates in it. For example, add the following lines to the program

```hates(amy, running).
likes(susie, X) :- hates(amy, X).
```
```?- likes(susie, What).