
-----------------------------------
wtd
Sun Apr 10, 2005 3:29 am

A Glimpse at Prolog
-----------------------------------
So, I've brought to attention all kinds of languages.  Let's look at one that's completely different.

Prolog

Prolog is a logic programming language.  With it we don't spell out sequences of statements to solve a problem.  Rather we build a database of known facts and rules and let the computer solve queries based on logical deduction.

Think my using the word database in their was a coincidence?  Aside from using dramatically different syntax, Prolog and SQL are not too distant cousins.

A Simple Example

Let's build a family tree.

male(joe).
male(brian).
male(david).

female(elizabeth).
female(diane).
female(clarise).

These are known facts.  Each line is a clause, terminated with a period.  Now, let's establish some relationships.  Each of these says "_ is the parent of _".

parentof(elizabeth, david).
parentof(david, brian).
parentof(david, clarise).
parentof(elizabeth, diane).
parentof(diane, joe).

These are well and good, but what if we want to add "fatherof" and "motherof" relations?  Should we write them out?  Nope, we already have enough information.

fatherof(F, C) :- male(F), parentof(F, C).

This is saying: "F is the father of C if F is male and F is the parent of C".  ":-" means "if", and "," means "and".  ";" means "or".  We'll see that one eventually.  Any name starting with a capital letter is a variable.

We can define "motherof" similary.

motherof(M, C) :- female(M), parentof(M, C).

What about a sibling relationship? 

siblingof(X, C) :- parentof(P, C), parentof(P, X), X \= C.

Here we say: "X is a sibling of C (known child) if P is a parent of C and P is a parent of X and X is not the same as C".

What about a grandparent relation?

grandparentof(G, C) :- parentof(P, C), parentof(G, P).

"G is a grandparent of C if P is a parent of C and G is a parent of P."

How do I work with this?

I'm currently using GNU Prolog and it seems to work well.  First save the code above in a file "fam.pl".  Then run the interpreter and use the consult predicate to loadthe file.

 $ gprolog
GNU Prolog 1.2.18
By Daniel Diaz
Copyright (C) 1999-2004 Daniel Diaz
| ?- consult('fam').
compiling /home/insaneones/Programming/Prolog/fam.pl for byte code...
/home/insaneones/Programming/Prolog/fam.pl compiled, 19 lines read - 2550 bytes written, 22 ms

(1 ms) yes
| ?-

Now, we can make a simple query.

| ?- siblingof(clarise, brian).

true ?

(1 ms) yes
| ?-

Or use a variable for a more complex query.

| ?- grandparentof(X, brian).

X = elizabeth ?

yes
| ?-

Exiting the interpreter is easy.  

| ?- halt.

-----------------------------------
Drakain Zeil
Sun Apr 10, 2005 8:44 am


-----------------------------------
I remember using prolog a few years back, is it that thing for AI? I might get back into it one day.

-----------------------------------
wtd
Sun Apr 10, 2005 2:29 pm


-----------------------------------
Another relatively simple example, this one showing a bit of output and recursion.

writeln(Msg) :- write(Msg), nl.
take_one_down :- writeln('Take one down, pass it around...').
bottles(0) :- writeln('No bottles of beer on the wall.').
bottles(1) :- writeln('One bottle of beer on the wall, one bottle of beer.'),
              take_one_down, bottles(0).
bottles(N) :- write(N), write(' bottles of beer on the walls.  '),
              write(N), writeln(' bottles of beer.'),
              take_one_down, NX is N - 1, bottles(NX).
