You are on page 1of 79

# 2/20/2013

Prolog Programming

## Introduction to logic programming

Declarative vs. procedural
Prolog components: facts, rules, queries
How logic programming works
Sample Prolog programs
Prolog exercise

1
2/20/2013

## Prolog (PROgramming in LOGic)

Declarative (though they also have a procedural element)
Knowledge engineer provides logic and specifies a goal to be
achieved
Specify what problem needed to be solved rather than how to solve it
Describe properties of objects and relations between them (i.e. using
if-then rules)
colour(roses, red). if cheeky(X) then happy(X)
cheeky(danial)
therefore happy(danial)
Non-procedural
Unlike conventional procedural languages (i.e. programmer specify
works out how to achieve the goal.

JAVA PROLOG

2
2/20/2013

## How logic programming works

Logic programming uses a collection of facts and
rules stored in the knowledge base.
Query as mode of operation
by posing queries (i.e. questions) about information in
the knowledge base

## and the following queries:

?- animal(fluffy). Is fluffy an animal?
?- cat(X). Is it possible to find cat?, lets call it X
?- cat(mischief). Is mischief a cat?
?- animal(belle). Is belle an animal?

3
2/20/2013

## For the 1st query: given that any X is an animal if

X is a cat, and fluffy is a cat, Prolog infers fluffy
is an animal.
For the 3rd query: mischief is not a cat -- on a
presumption that, as far as the program is
concerned, what is not currently known to be true
is false (i.e. closed world assumption).
For the 4th query: rules declare things that are
true depending on a given condition/facts.

4
2/20/2013

## Write a program to put the following logical

statement into Prolog rule.

## By adding appropriate facts into a knowledge

base and posing queries, try to understand how
Prolog derives answers to the queries.

cheeky(danial).
% danial is cheeky

happy(X) :- cheeky(X).
% For all X, X is happy if X is cheeky

?- cheeky(X).
X = danial

?- happy(X).
X = danial

?- happy(danial).
yes

?- cheeky(danial).
yes

5
2/20/2013

## PROLOG: Programming for Artificial Intelligence by Ivan Bratko

6
5/3/2013

Prolog Programming

## Prolog consists of data object of different

types:
atoms, numbers, variables, compound terms such
as structures, and lists
they differ by its syntactic form
Also called terms

1
5/3/2013

## An atom can be written in several ways:

begins with a lower-case letter followed by letters
(either case) or digits, or the underscore character.
cheeky red_apple wAES2106
using special characters + - * / = < > : . ~ which
may be in the form of sequence of characters or a
single character
:- predefined meaning in Prolog, read as if
% for insertion of a line of comment
a string of any characters enclosed within single
quotes.
WAES2106 123abc Kuala Lumpur Suite 12-8

## Consists of sequence of integer or real

numbers
with/without a + or sign
may contain a single decimal point, anywhere
except before a + or - sign
-123 +25 12.3 -.123 +246.

2
5/3/2013

## Begins with a capital letter, which can be

followed by letters (either case) or digits, or
the underscore character.
X123 Y Zara Kuala_Lumpur
Anonymous variables
using the underscore character _ for such case
where we are not interested to know the value of a
particular variable
for all Y, Y is a mother if Y has a daughter
mother(Y) :- daughter(_,Y).

## Begins with an atom, known as functor,

followed by one or more arguments (separated
by a comma) and enclosed within parentheses.
Each argument is a term of any kind
(including a compound term)
Number of arguments is called its arity
colour(roses, red) happy(X) likes(myra, durian)
student('Sarah Ahmad', dob(12, february, 2000), age(12))
substract(10, 2, 8)

3
5/3/2013

## An ordered collection of terms of any kind

(separated by a comma) and enclosed within
square brackets
[ ] an empty list
['kuala lumpur', 'shah alam', kuching]
[[white, blue, green], [yellow, orange, red]]
[prolog, ali, publication_year(22, january, 2012)]

## To satisfy a goal, Prolog works through the

clauses in the KB in turn, from top to bottom
until a match is found.
happy(X) and happy(danial) are identical, thus can
be matched/unified by instantiating variable X to
danial (i.e. giving X the value)

4
5/3/2013

## If Term1 and Term2 are constants, then they

match only if they are the same object
apples = apples

## If Term1 is a variable and Term2 is anything,

then they match. Term1 is instantiated to
Term2 (and vice versa)
likes(myra, X) = likes(Y, chocolate)
X = chocolate Y = myra

## If Term1 and Term2 are structures, then they

match only if
Term1 and Term2 have the same principal functor
all their corresponding components match
date(D,F, 2012) = date(D1, february, Y1)
D = D1 (binds two differently named variables to single,
unique variable)
F = february (F is instantiated to february )
Y1 = 2012 (Y1 is instantiated to 2012)

5
5/3/2013

## Term 1 Term 2 Match?

doll X
parent(X, sarah) Y
colour (blue, green, yellow) colour(X, Y)
colour (a, b, c) col(a, b, c)
a b
parent(X, Y, Z) parent(ali, 35, doctor)
[a, cake(X, Y), B) [Q, R, c]

## Term 1 Term 2 Match?

doll X Succeed
X = doll
parent(X, sarah) Y Succeed
Y = parent(X, sarah)
X is still unbound
colour (blue, green, yellow) colour(X, Y) Fails. The terms have different arity
colour (a, b, c) col(a, b, c) Fails. The terms have different functor

## a b Fails as they are not identical

parent(X, Y, Z) parent(ali, 35, doctor) Succeed. X, Y, Z are instantiated to ali,
35, doctor, respectively
[a, cake(X, Y), B] [Q, R, c] Succeed.
Q=a
R = cake(X, Y)
B=c

6
5/3/2013

## chases(X,Y) :- cat(X), bird(Y).

determines how Prolog satisfies a list of goals
depend on the order of goals and clauses
The procedural meaning is to satisfy chases(X,Y), first satisfy
cat(X), then satisfy bird(X)

big(bear).
big(elephant).
small(cat).
brown(bear).
black(cat).
gray(elephant).

dark(Z) :- black(Z).
dark(Z) :- brown(Z).

?- dark(X), big(X).

7
5/3/2013

## Consider the following rule:

chases(X,Y) :- cat(X), bird(Y).
Determines whether a given goal is true and if so, for
what values of variables it is true.
The declarative meaning says chases(X,Y) is true if X and Y are
true

A variant of a clause C
an instance of the clause C where each variable is substituted by another
variable

An instance of a clause C
the clause C with each of its variables substituted by some term

8
5/3/2013

## Given a program and a goal G, the declarative

meaning says:
G is true if and only if:
(1) there is a clause (i.e. C) in the program such that
(2) there is a clause instance (i.e. I) of C such that
(a) the head of I is identical to G, and
(b) all the goals in the body of I are true

male(tom).
parent_of(tom,sarah).

father_of(X,Y):-parent_of(X,Y), male(X).

G is father_of(tom,Y)

and then

9
5/3/2013

## Write a program to put the following logical statement into

Prolog rule.
For all X and Y,
X will be jealous of Y if
X likes Z and
Y likes Z
By adding appropriate facts into a knowledge base and
posing the query, ?- jealous(X,Y), try to understand
and trace how Prolog derives answer(s) to the query.

likes(irfan, zara).
likes(danial, zara).
jealous(X, Y):-
likes(X, Z),
likes(Y, Z).

## Consider the following query, ?- jealous(X, Y). There are four

ways Prolog can satisfy the query. Work through the program carefully
and explain how does Prolog answer the above query by giving four
different solutions.

10
5/3/2013

## PROLOG: Programming for Artificial Intelligence by Ivan Bratko (4th

11
15/3/2013

Prolog Programming

## Proof search (and search tree)

How Prolog searches a KB to see if a query is
satisfied.
Constructing Prolog program
family.pl

1
15/3/2013

## Prolog process query, searching the KB in left

to right depth-first order to find out whether
a query can be satisfied.

p(a). ?- w(What).
p(b).
q(a).
q(b).
r(b).
w(X) :- p(X), q(X), r(X).

?- w(What).

2
15/3/2013

p(a). ?- w(What).
p(b). What = X
q(a). ?- p(X), q(X), r(X).
q(b).
r(b). X=a X=b
w(X) :- p(X), q(X), r(X).
?- q(a), r(a). ?- q(b), r(b).
?- w(What).
What = b ?- r(a). ?- r(b).

Fails backtrack!

## likes(irfan, zara). ?- jealous(X,Y).

likes(danial, zara).

jealous(X, Y):-
likes(X, Z),
likes(Y, Z).

?- jealous(A, B).

3
15/3/2013

## likes(irfan, zara). ?- jealous(X,Y).

likes(danial, zara). X=A Y=B
?- likes(X,Z), likes(Y,Z).
jealous(X, Y):-
likes(X, Z), X = irfan Y = zara X = danial Y = zara
likes(Y, Z).
?- likes(Y,zara) ?- likes(Y,zara)
?- jealous(A, B).

X= Y = irfan
X = irfan Y = danial
Y = irfan Y = danial Y = irfan Y = danial
X = danial Y = irfan
X = Y = danial

## Consider the following Prolog clauses:

v('A').
v(a).
x(b).
w(c,'A').
w(c, b).
m(X,Y,Z):-v(X), x(Y), w(Z,X).
Give all the variable instantiations during Prolog execution for the query
?- m(X,Y,_). Use backtracking to force Prolog to find more than one
solution. Where relevant, indicates whether the instantiations lead to
failures.
Draw the proof search tree for the query.

4
15/3/2013

## v('A'). Variable instantiations during Prolog execution.

v(a). Step 1
x(b). X = A
w(c,'A'). Y=b
Z=c
w(c, b).
m(X,Y,Z):-v(X), x(Y), w(Z,X). Step 2 (backtrack)

?- m(X,Y,_). X = A
Y=b
Z=c
X = A
b\= A
Y=b;
Step 3 (backtrack)
no.
X=a
Y=b

A \= a
b \= a

Write a Prolog program called family.pl which contains information about family of
three generations as shown below.

- father
- mother
- sister
- aunty
- cousin

5
15/3/2013

## What will be Prologs answers to the following queries?

sister(X,Y).

father_of(david,_).

aunty(X, james).

aunty(patricia, dora).

cousin(james, X).

## mother_of(X,betty), aunty(X, james).

\+parent_of(tom, patricia).

6
15/3/2013

## ?- sister(X, Y). ?- father_of(david, _). Conjoined goals AND

yes ?- mother_of(X, betty), aunty(X, james).
X = sarah , X = sarah ;
Y = max ; ?- aunty(X, james).
X = sarah ; no
X = sarah ,
Y = patricia ; no Negative goal NOT
?- \+parent_of(tom, patricia).
X = patricia ,
?- aunty(patricia, dora). no
Y = max ;
yes
X = patricia , Disjoint goals OR
Y = sarah ; ?- parent_of(max, _); cousin(max, betty).
Backtracking produced
duplicate results! Prolog no
X = dora ,
Y = betty ;
as separate pieces of data. ?- cousin(james, X).
X = betty , X = dora ;
Y = dora ;
no X = betty ;

no

## Consider the following clause:

play(dora, doll).

## ?- play(dora, What). % Dora plays with what?

What = doll.

go:-play(dora, What),
write('Dora likes to play with '), write(What), nl.

## predicate go/0 (with no argument) enables query to be entered brief, i.e.

?- go.
Dora likes to play with doll
yes

7
27/3/2013

Prolog Programming

## So far, we used functor, followed by a number of arguments in

parentheses to represent fact, e.g. likes(myra, durian)
As alternative, the fact can be written using infix operator.
This enables functor (i.e. likes) to be written between the two
arguments with no parentheses: myra likes durian.
To aid readability, you may write rule such as:
likes(dora, X) :- cat(X)
as dora likes X :- X is a cat.

1
27/3/2013

## To perform arithmetic calculations:

- subtraction
* multiplication
/ division The result is the whole number part of a division
mod remainder The result is the remainder of a division
sqrt(X)

?- X is 1 + 2.
X=3

?- X is 3 + 5
X=8

## X>Y X is greater than Y

X<Y X is less than Y
X >= Y X is greater than or equal to Y
X =< Y X is less than or equal to Y
X =:= Y the values of X and Y are equal
X is Y X is Y, if X matches the value of Y (where X is a variable or a constant
and Y is an arithmetic expression
X \== Y X is not literally equal to Y
X=Y X is equal to Y, if X and Y match
Examples:
?- 4 > 3. ?- 2 =:= 2.
yes yes
?- X is 2 + 2, X < 2. ?- 2 \== 3.
no yes
?- X is 2 + 2. ?- zara = zara.
X=4 yes

2
27/3/2013

?- Y is 10, Z is Y+1.
?- X is sqrt(36).
?- 10 is 7+13-11+9.
?- 88+15-3=:=110-5*2.
?- 6+4=:=6*3-8.
Consider the following rules:
greater_than(X,Y) :- X > Y.
and the following queries:
?- greater_than(2,5).
Define a predicate sum that holds only when its 3rd argument is the sum of
the first two arguments. For example, sum(1,2,3) should hold, but
sum(2,2,5) should not

Y = 10 , Z = 11
X=6
no
yes
yes
no
Y = 10
sum(X, Y, Z) :- Z is X+Y.

3
27/3/2013

## In ordinary arithmetic, 1+2*3 means (1+(2*3)) and 6-3-1 means (6-3)-1

(i.e. from left to right - equal precedence). Prolog follows the ordinary
arithmetic standard usage.
1+2*3 expression has the structure +(1,*(2,3))
6-3-1 has the structure -(-(6,3),1)

## Consider the following expression:

a+b*c
In Prolog, the convention is that, operators with lower precedence bind
stronger
The operator with the highest precedence in a term is the principle functor
of the term.
Therefore in Prolog, the precedence of + is defined higher than the
precedence of * (and therefore * binds stronger than +).
The precedence of operators decides what is the correct interpretation of an
expression, and so the expression a + b * c is understood as +(a,*(b, c))
and not as *(+a,b),c).

4
27/3/2013

## Prolog operators: binary

Infix: An infix operator appears between its two arguments (e.g. 2+3)
xfx non-associative
xfy right to left
yfx left to right
Prolog operators: unary

## Prefix: Prefix operator appears before its single argument (e.g. 8)

fx non-associative
fy left to right

Postfix: Postfix operator appears after its single argument (e.g. 2 factorial)
xf non-associative
yf right to left

The definition of an operator includes three parts and is accomplished by issuing a directive
to Prolog.
op(<Precedence>, <Type>, <Operator>)

<Precedence> is an integer between 1 and 1200, the higher the number, the higher the
precedence of the operator. Atoms always have precedence 0.
<Type> is one of
xfx, xfy, yfx for binary operators,
fx, fy for prefix unary operators,
xf, yf for postfix unary operators
<Operator> is an atom or a list of atoms that represents the operator symbol(s). It is possible
to define two operators with the same symbol, as long as the type of each is different i.e.
infix, prefix or postfix.
xfx is non associative operator, which suggests that the operator is between two arguments.
f stands for the operator which acts as a point of reference to distinguish between the left
and right arguments (left or right for unary operators).
'x' and 'y' denote arguments.
xfy defines a right-associative operator and the type yfx, a left-associative operator.

5
27/3/2013

:-op(300,yfx,-). :-op(300,xfy,-).

?- display(4-1-2). ?- display(4-1-2).
-(-(4,1),2) -(4,-(1,2))
yes yes

?- X is 4-1-2. ?- X is 4-1-2.
X=1 X = 5 wrong

:-op(500,yfx,-). :-op(300,yfx,-).
:-op(400,yfx,/). :-op(400,yfx,/).

?- display(5-6/2). ?- display(5-6/2).
-(5,/(6,2)) /(-(5,6),2)
yes yes

?- X is 5-6/2. ?- X is 5-6/2.
X=2 X = -0.5 wrong

6
27/3/2013

## :- op(500, yfx, [+,-]). :- op(500, xfy, [+,-]).

?- display(3-2+1). ?- display(3-2+1).
+(-(3,2),1) -(3,+(2,1))
yes yes

?- X is 3-2+1. ?- X is 3-2+1.
X=2 X = 0 wrong

:-op(500,yfx,+). :-op(400,yfx,+).
:-op(400,yfx,*). :-op(500,yfx,*).

?- display(1+2*3). ?- display(1+2*3).
+(1,*(2,3)) *(+(1,2),3)
yes yes

?- X is 1+2*3. ?- X is 1+2*3.
X=7 X = 9 wrong

7
27/3/2013

## :- op(1200, xfx, [:-, -->])

:- op(1200, fx, [:-, ?-])
:- op(1100, xfy, ';)
:- op(1050, xfy, ->)
:- op(1000, xfy, ,)
:- op(700, xfx, [=, \=, ==, @<. @=<. @>, @>=, is,
=:=, =\=, <, >, =< <=, >=])
:- op(500, yfx, [+, -])
:- op(400, yfx, [*, /, //, mod])
:- op(200, xfx, **)

## Using Prolog predefined arithmetic operators as follows:

:-op(500,yfx,[+, -]).
:-op(400,yfx,[/, *]).

## What is the structure of the following arithmetic expression?

6/3-1*2+3

8
27/3/2013

?- display(6/3-1*2+3).
+(-(/(6,3),*(1,2)),3)
yes

## :-op(600, xfx, likes). :-op(100,fy,turn_on).

likes(myra,durian). turn_on(the_tv).

## ?- myra likes What. ?- turn_on the_tv.

What = durian yes

?- turn_on What
What = the_tv

9
27/3/2013

## and the following operator definitions:

:- op(300,xfx,likes).
:- op(200,xfy,and).

## Note that, an operator for 'and' can be defined as right-associative operator

according to Bratko (Prolog Pogramming for Artificial Intelligence).

structure?

## danial likes What.

What = drawing
danial likes drawing and What.

10
27/3/2013

## Define appropriate operators (and, inside) to be able to write

sentence as follow:

## ?- What and What2 inside blue_box inside red_box

What = ball
What2 = marble

:-op(300,xfy,and).
:-op(400,yfx,inside). % left associative

What = ball ,
What2 = marble

11
27/3/2013

## For all X and Y,

X chases Y if X is a dog and Y is a cat.

## Define appropriate operator chases so that Prolog can answer

the following query:

## ?- Who chases Whom.

:-op(700,yfx,chases).

cat(tom).
dog(buddy).

Who = buddy ,
Whom = tom

12
27/3/2013

## PROLOG: Programming for Artificial Intelligence by Ivan Bratko

13
29/3/2013

Prolog Programming

## Prolog offers 2 ways to perform computations repetitively:

Backtracking (more on this in the next few lectures)
Recursion

Recursive programming
One of the most basic and most important concepts in computer
science (and mathematics) in general.

1
29/3/2013

## The basic idea of recursion principle is the following:

To solve a complex problem, provide the solution for the simplest
problem of its kind (i.e. base case) and provide a rule for transforming
such a (complex) problem into a slightly simpler problem (i.e. a recursion
rule)
Recursive rule means a rule calls itself until some final point is reached (i.e.
the base case).
In Prolog what this means is that we have a first fact that acts as some
stopping condition followed up by some rule(s) that performs some
operation before reinvoking itself.

squares:

1 1
2 4
3 9
4 16
5 25

2
29/3/2013

## The recursive algorithm for the problem is as follows:

To print square beginning with N:
If N > 5,
print bye
Otherwise,
print N and N2, then print squares beginning with N + 1.

Exercise
Now, transform the above algorithm into Prolog clauses.

In Prolog:

## print_squares(N) :- N > 5, write(bye), nl.

print_squares(N) :-
S is N * N,
write(N), write(' '), write(S), nl,
M is N + 1,
print_squares(M).

3
29/3/2013

## The sample of query is as follows:

| ?- print_squares(1).

1 1
2 4
3 9
4 16
5 25
bye
yes

Write a Prolog program to print integers from Last to First inclusive. The
sample run is as follow:

?- print_integers(5,2).
5
4
3
2
end

yes

4
29/3/2013

## print_integers(First, First) :- write(First), nl,

write('end'), nl.

## print_integers(Last, First) :- Last=\=First,

write(Last), nl,
N is Last-1,
print_integers(N, First).

## Consider facts and a rule given below:

en_route(kajang).
en_route(Place):-
travel(Place,Travelling_by,NewPlace),
en_route(NewPlace).

travel(brighton,train,london).
travel(london,plane,dubai).
travel(dubai,plane,kuala_lumpur).
travel(kuala_lumpur,car,kajang).

?- en_route(brighton).

5
29/3/2013

## What happens when we submit this query :

?- en_route(brighton).

What is Factorial?
The factorial N! of a natural number N is defined as the product
of all natural numbers from 1 to N.
The factorial of 1 is 1.
The factorial any larger integer N is N times the factorial of N-1.

6
29/3/2013

## Heres a more formal, recursive definition:

1! = 1 (base case)
n! = (n 1)! n for n > 1 (recursion rule)

## What is the answer for 5! ?

5! = 5 x 4 x 3 x 2 x 1 = 120

## factorial(N, Result) :- % recursion step

N > 1,
N1 is N - 1,
factorial(N1, Temp),
Result is Temp * N.

## Provide Prolog trace for:

?- factorial(3, Result).

7
29/3/2013

How it works?
To compute the 3! we have to pass through the second part of
that definition 2 times until we get to the base case and are able
to calculate the overall result.
The procedure factorial calls itself to compute the factorial of the
next smaller integer, then uses the result to compute the factorial
of the integer, 3.
The recursion stops when the number whose factorial is to be
computed is 1.

8
18/4/2013

Prolog Programming

## Lists is a sequence of Prolog objects of any kind and

can also be lists.
An empty list in Prolog:
[]
A non empty:
[violet, indigo, green, yellow].
The first item (i.e. violet) is the head of the list.
The remaining part of the list is the tail.
The head can be any Prolog data objects, however,
the tail has to be a list.

1
18/4/2013

What are the head and tail for the following lists?
[do, [re, mi]]
[do, re, [mi]]
[[do]]
[do, [re], mi]
Example of prolog query:
?- [Head | Tail] = [do, re, mi].
Head = do, Tail = [re, mi]

2
18/4/2013

## [do, [re, mi]]

Tail = [[re, mi]]
[do, re, [mi]].
Tail = [re, [mi]]
[[do]]
Tail = []
[do, [re], mi]
Tail = [[re], mi]

Given the lists 1 and 2 below, what are the values for the instantiated
variables?

Lists 1 Lists 2
[X, Y | Z] [do, re, mi]

[re] [X | Y]

## ?- [X, Y | Z] = [do, re, mi].

X = do, Y = re, Z = [mi]

3
18/4/2013

[re] = [X | Y].
X = re,
Y = []
[Orange | Apple] = [[do], re, mi].
Orange = [do],
Apple = [re,mi]
[X | [Y | [Z | W]]] = [do, re, mi].
X = do,
Y = re,
Z = mi,
W = []

## Checking if some object is an element of a list.

Concatenating of two lists to obtain a third list.
Counting the length of a list (i.e. number of
elements the list contains).
Adding a new object to a list
Deleting some object from a list.
Sublist such that a list S occurs within L as its
sublist.
Permutating a list such that one list is a
permutation of the other list.

4
18/4/2013

## The membership relation can be based on either of the

following cases:
X is the head of L
X is a member of the tail of L, if it can be proved that
X is a member of the Tail
In Prolog clauses:

member(X, [X | Tail]).

member(X, Tail).

query:

5
18/4/2013

## The concatenation relation can be based

on either of the following cases:
If the 1st argument is the empty list
then the 2nd and the 3rd argument
must be the same list, i.e.
conc([], L, L).
If the first argument of is non-empty
list then it has a head and a tail, i.e.
[X|L1]
For example:
conc([1, 2], [3, 4], [1, 2, 3, 4])

6
18/4/2013

In Prolog clauses:
conc([X | L1], L2, [X | L3]):-
conc(L1, L2, L3)
conc can be used (in the inverse direction) to decompose a given
list into two lists, e.g.
?- conc(L1, L2, [1, 2, 3]).
L1 = []
L2 = [1, 2, 3];
L1 = 
L2 = [2, 3];
L1 = [1, 2]
L2 = ;
:

## Describe how Prolog solve the following

query:

?- my_conc([a,b],[c,d],R).

7
18/4/2013

## Can be based on either of the following cases:

If the list is empty, then its length is 0
If the list is not empty then List = [Head | Tail];
then its length is equal to 1 plus to the length of the
tail Tail
In Prolog clauses:
length([],0).
length([_| Tail], N):-
length(Tail,N1), N is N1+1.

8
18/4/2013

## To add an item, i.e. X in front of the list, thus becomes the

In Prolog clause: add(X, L, [X | L]).
For example:

X = 2,
L = [3,4]

N = [2,3,4,5]

## Can be based on either of the following cases:

If X is the head of the list then the result (after the deletion)
is the tail of the list
If X is in the tail then it is deleted from there
In Prolog clauses:
del(X, [X | Tail], Tail).
del(X, [Y | Tail], [Y | Tail1]):-
del(X, Tail, Tail1).
For example:
del(a, [a, b, a], L).
L = [b, a];
L = [a, b];

9
18/4/2013

## del can be used (in the inverse direction) to insert

a new item anywhere in the list.
For example:
?- del(z, L, [1, 2, 3]).
L = [z, 1, 2, 3];
L = [1, z, 2, 3];
L = [1, 2, z, 3];
L = [1, 2, 3, z];
no

## The sublist relation can be based on either of the

following cases:
L can be decomposed into two lists, giving L1 and
L2
L2 can be further decomposed into two lists, giving
S and some L3.
In Prolog clauses:
sublist(S, L) :- conc(L1, L2, L),
conc(S, L3, L2).

10
18/4/2013

For example:
sublist([1, 2, 3], [0, 0, 1, 2, 3, 4])

Can also be used to find all sublists of a given list, for example:
?- sublist(S, [1, 2, 3]).

S = [];
S = ;
S = [1, 2];
S = [1, 2, 3];
S = [];
S = ;
:
:

## The permutation relation can be based on either of the following

cases:
If the first list is empty then the second list is also empty
If the first list is not empty -- first permute L obtaining L1 and
then insert X at any position into L1.

In Prolog clauses:
permutation ([], []).
permutation ([X | L], P):-
permutation(L, L1),
insert(X, L1, P).

insert(X,List,AnotherList):-
del(X,AnotherList,List).

11
18/4/2013

For example:
?- permutation([apple, berry, cherry], P).
P = [apple,berry,cherry] ;
P = [berry,apple,cherry] ;
P = [berry,cherry,apple] ;
P = [apple,cherry,berry] ;
P = [cherry,apple,berry] ;
P = [cherry,berry,apple] ;
no

## PROLOG: Programming for Artificial

Intelligence by Ivan Bratko (Addison Wesley)

12
25/05/2013

Prolog Programming

##  Problems with Cuts

 Negation as Failure

 Using fail
 Backtracking using fail
 Cut using fail

1
25/05/2013

##  Sometimes we need a way to prevent Prolog finding all solutions,

i.e. a way to stop backtracking.

##  The cut operator ! is a predefined Prolog predicate that prevents

backtracking and can be placed anywhere inside a rules body.

##  Executing the subgoal ! will always succeed, but afterwards,

backtracking into subgoals placed before the cut inside the same
rule body is not possible anymore.

p(1).
p(2) :- !.
p(3).

##  Write all Prologs answers to the following queries:

?- p(X).
?- p(X), p(Y).
?- p(X),!,p(Y).

2
25/05/2013

?- p(X). ?- p(X),!,p(Y).
X = 1 ; X = Y = 1 ;

X = 2 X = 1 ,
Y = 2
?- p(X), p(Y).
X = Y = 1 ;

X = 1 ,
Y = 2 ;

X = 2 ,
Y = 1 ;

X = Y = 2

##  max, without cut:

max(A, B, A) :- A > B.
max(A, B, B) :- A =< B.

?- max(2, 5, X).
X = 5

?- max(3, 1, X).
X = 3 ;

 These two rules are mutually exclusive. If the first one succeeds then the
second one will fails, and vice versa.

3
25/05/2013

##  max, with cut:

max(A, B, A) :- A > B, !.
max(A, B, B).

?- max(3, 5, X).
X = 5

?- max(3, 1, X).
X = 3

## Represent the following facts in Prolog form.

4
25/05/2013

marks(N,A) :- N>=80,!.
marks(N,B) :- N>=65,!.
marks(N,C) :- N>=55,!.
marks(N,D) :- N>=50,!.
marks(N,pass) :- N>=40,!.
marks(N,fail) :- N<40.

## % shopping day on weekend in fair weather and on public

% holiday

holiday(friday, feb1).
holiday(wednesday,may1).
weekend(saturday).
weather(saturday,fair_weather).

shopping(Day) :- holiday(Day,_), !.
shopping(Day) :- weather(Day, fair_weather), weekend(Day).

## 1. Explain how Prolog respond to the query, ?- shopping(When).

2. What can you conclude from Prolog program in exercise 2 and 3?

5
25/05/2013

##  Cut changes the declarative meaning of the program.

 Need to use it with care only where needed.
 Green cuts can be inserted for efficiency (i.e. program
in exercise 2).
 Red cuts should be considered carefully (i.e. program
in exercise 3).

##  Cuts are very useful to guide the Prolog interpreter towards a

solution.
 However, by introducing cuts, we give up some of the declarative
meaning of Prolog towards a more procedural meaning.
 This can sometimes lead to unexpected results.
 Two types of cut:
 Green cut: makes a program more efficient without affecting the
set of solutions that the program generates
 Red cuts: prevents the program from generating solution it would
otherwise give

6
25/05/2013

##  Sometimes we might not want to ask whether a certain goal

succeeds, but whether it fails.

proof for Goal.

##  Consider the following facts:

married(ben, nancy).
married(chong, julia).
married(dani, damia).

##  Then we can define single/1 that succeeds if the argument given

can neither be found as the first nor as the second argument in any
of the married/2 facts.

7
25/05/2013

##  Consider the following predicate, single/1:

single(Person) :-
\+ married(Person, _),
\+ married(_, Person).
% use anonymous variable because its value would be
% irrelevant.

##  and the following queries:

?- single(damia).
no
?- single(nour).
yes

be married.

##  Where to use \+:

 The \+ operator can be applied to any valid Prolog goal.

##  Goals are either:

(sub)goals of a query or
(sub)goals of a rule-body.

##  Facts and rule-heads arent goals. Hence, it is not possible to

negate a fact or the head of a rule.

8
25/05/2013

##  fail is a symbol that will immediately fail when Prolog encounters

it as a goal. When fails, Prolog tries to backtrack.

##  fail used in combination with automatic backtracking allow Prolog

to search through the KB to find all possible values of X that satisfy
the goal, say for example, list_all(X).

##  Consider the following KB:

candy(vanilla).
candy(strawberry).
candy(chocolate).

## list_all :- candy(X), write(X),

write( flavoured candy), nl, fail.
list_all.

##  How does Prolog respond to the query, ?- list_all.

 The second clause list_all. ensure that, after the KB has been
searched, the goal succeeds. However, with only the first line, any call
to list_all. will eventually fail.

9
25/05/2013

##  Suppose the KB contains the following clauses.

bird(robin).
bird(parrot).
bird(penguin).
can_fly(X) :- bird(X).
 The following query, ?- can_fly(penguin) gives
undesired result. Why?
 If we add new clause, can_fly(penguin):- fail. and
having the clause, can_fly(X) :- bird(X).
immediately following the new clause, the query still gives
undesired result. Why?
 How can we solve this problem using fail?

##  The desired result can be achieved by defining the new clause as

follow:

bird(robin).
bird(parrot).
bird(penguin).
can_fly(penguin):- !, fail. % cut with failure
can_fly(X) :- bird(X).

##  Cut using fail helps to specify few exceptions to general rules, in

this case, penguin cannot fly.
 But, if we pose the query, ?- can_fly(X) -- the answer is no.
How do we solve the problem?

10
25/05/2013

bird(robin).
bird(parrot).
bird(penguin).
can_fly(X) :- bird(X), X \== penguin .

##  Write a program that repeatedly prompts the user to enter series of

numbers and outputs a message indicating whether each is an odd
or even number. The program stops when the user has entered 10
numbers.

11
25/05/2013

##  Write a program that repeatedly prompts the user to enter series of

numbers and outputs a message indicating whether each is an odd
or even number. The program stops when the user has entered a
number 10.

12
25/05/2013

## likes(lina,X) :- candy(X), X == 'Orange', !, fail.

likes(lina,X) :- candy(X).

candy(X) :- candy_flav(X).

candy_flav('Strawberry').
candy_flav('Lemon').
candy_flav('Mint').

## The queries, ?- likes(lina, Mint), yes

?- likes(lina, Orange), no

## Explain how Prolog responds to the above queries.

13
5/25/2013

Prolog Programming

##  Testing the types of terms

 Constructing and decomposing terms: =.., functor, arg
 Testing for equality and comparisons (see lecture note on arithmetic
and operations)
 Control facilities: !, fail, true, not(P), repeat, if-else construct
 Database manipulation
 Finding solutions: bagof, setof, findall
 Input and output

1
5/25/2013

##  Predicates: var, nonvar, atom, integer, float, number, atomic,

compound
 var(Y): succeeds if Y is currently an uninstantiated variable.
 nonvar(Y): succeeds if Y is not a variable, or Y is an already
instantiated variable.
 atom(Y): checks if Y is instantiated to an atom.
 integer(Y): checks if Y is instantiated to an integer.
 float(Y): checks if Y is instantiated to a real number
 number(Y): checks if Y is instantiated to a number.
 atomic(Y): true if Y is either an atom or a number
 compound(Y): checks if Y is instantiated to a compound term (i.e.
a structure).

## ?- var(Y), Y =2. ?- atom('cake').

Y = 2 yes

?- X = 2, var(X). ?- atomic(22.5).
no no

?- atom(cake). ?- compound(mm(s)).
yes yes

?- atom(2).
no

2
5/25/2013

##  Predicates: =.. , functor, arg

 Term =.. L
 Written as an infix operator and reads as univ. The goal Term =.. L
is true if L is a list that contains the principle functor of Term,
followed by its arguments.
Term =.. [Functor | ArgumentList]

?- a(b,c) =.. L.
L = [a,b,c]

?- Z =..[p,1,2].
Z = p(1,2).

 functor(Term, F, N)
 True if F is the principal functor of Term and N is the arity of F.

## ?- functor(t(a, b, c), X, Arity)

X = t
Arity = 3

3
5/25/2013

 arg(N, Term, A)
 True if A is the Nth argument of Term, numbering left to right from 1.

X = b

## ?- arg(3, f(a, x(b), y(c)), Z).

Z = y(c)

 !
 reads as cut, prevents backtracking

 fail
 a goal that always fails

 true
 a goal that always succeeds

 not(P)
 negation as failure

4
5/25/2013

 Repeat
 Is use to do a loop. The predicate in which it is used is repeated
until every goal succeeds.

pword :- repeat,

?- pword.
yes

 (P -> Q; R)
 Is an if-then-else construct. It read as: if P then Q else R. The
arrow -> is an infix operator whose priority is less than that of ;
and greater than that of a comma.

## ?- X = 10, Y = 15, (X >= Y -> Colour = pink; Colour

= green).
X = 10 ,
Y = 15 ,
Colour = green

5
5/25/2013

 Prolog 'throws away' old solutions (and is not accessible any more)
as it backtracks to generate new solution. The predicates bagof,
setof and findall can be used if we prefer to have all generated
solutions available.
 bagof( X, P, L)
 This produces a list L of all the objects X such that a goal P is
satisfied.
 setof( X, P, L)
 This produces a list L of all the objects X that satisfy P. This time,
duplicate items will be eliminated and it defines the ordering
among terms.
 findall( X, P, L)
 Similar to bagof.
The difference: findall will return an empty list if a goal P has
no solutions, whereas bagof would fail in such situation.

## Consider the following KB:

likes(myra, durian).
likes(danial, strawberry).
likes(zara, orange).
likes(irfan, durian).
likes(lana, apple).

Child = _ ,
L = [myra,irfan]

## ?- bagof(Child, Fruit ^ likes(Child, Fruit), L).

Child = _ ,
Fruit = _ ,
L = [myra,danial,zara,irfan,lana]

6
5/25/2013

## ?- bagof(Child, likes(Child, Fruit), L).

Child = _ ,
Fruit = apple ,
L = [lana] ;
Child = _ ,
Fruit = durian ,
L = [myra,irfan] ;
Child = _ ,
Fruit = orange ,
L = [zara] ;
Child = _ ,
Fruit = strawberry ,
L = [danial] ;

## ?- bagof(Fruit, likes(Child, Fruit), L).

Fruit = _ ,
Child = danial ,
L = [strawberry] ;
Fruit = _ ,
Child = irfan ,
L = [durian] ;
Fruit = _ ,
Child = lana ,
L = [apple] ;
Fruit = _ ,
Child = myra ,
L = [durian] ;
Fruit = _ ,
Child = zara ,
L = [orange] ;

7
5/25/2013

likes(myra, durian).
likes(danial, strawberry).
likes(zara, orange).
likes(irfan, durian).
likes(lana, apple).

## ?- setof(Child, Fruit ^ likes(Child, Fruit), CList),

setof(Fruit, Child ^ likes(Child, Fruit), FList).
Child = _ ,
Fruit = _ ,
CList = [danial,irfan,lana,myra,zara] ,
FList = [apple,durian,orange,strawberry]

## ?- setof(Fruit/Child, likes(Child, Fruit), L).

Fruit = _ ,
Child = _ ,
L = [apple/lana, durian/irfan, durian/myra,
orange/zara, strawberry/danial]

likes(myra, durian).
likes(danial, strawberry).
likes(zara, orange).
likes(irfan, durian).
likes(lana, apple).

## ?- findall(Child, likes(Child, Fruit), L).

Child = _ ,
Fruit = _ ,
L = [myra,danial,zara,irfan,lana]

## ?- findall(Child, likes(Child, banana), L).

Child = _ ,
L = []

If there is no object X that satisfy condition P, then findall will succeed with
L = [ ]. Note that if the query ?- bagof(Child, likes(Child,
banana), L), then bagof will not succeed.

8
5/25/2013