Artificial Intelligence
Lecture 9
Logic programming and Prolog
8-12-2022
Logic programming
Program in imperative languages (C++, Java, …) is
a description of sequence of instructions to be
executed one-by-one by a target machine to solve the
given problem.
The description of the problem is implicitly incorporated in
this instruction sequence, where usually it is not possible to
clearly distinguish between the description (i.e., logic) of the
problem, and the method (i.e., control) used for its solution.
In logic programming language, the description of the
problem and the method for its solution are explicitly
separated from each other.
Logic programming
Algorithm = Logic + Control
what how
Horn clauses resolution
• Logic represents the descriptive part of a problem, i.e.,
what the algorithm is supposed to do, and
• Control represents the solution part, i.e., how the solution is to
be done.
Prolog
Prolog is the most widely used logic programming
language.
Prolog is the programming language for AI based on
first order logic.
Prolog is implemented in two parts:
Logic, which describes the problem, and
Control, provides the solution method.
Prolog is an abbreviation of Programming in logic.
Its application area includes:
AI, Natural Language Processing, Design of expert system.
Prolog (cont.)
Prolog programs are sets of definite clauses.
Prolog uses uppercase letters for variables and
lowercase for constants—the opposite of FOL
convention.
Program = set of clauses of the form:
head :- literal1, …, literaln.
Commas separate conjuncts in a clause, and the clause
is written “backwards” from what we are used to:
The FOL statement A ∧ B ⇒ C is written in Prolog as
C :- A, B.
Prolog (cont.)
For example, the FOL statement:
American(x) ∧ Weapon(y) ∧ Sells(x, y, z) ∧ Hostile(z) ⇒
Criminal(x)
is written in Prolog as:
criminal(X) :- american(X), weapon(Y), sells(X,Y,Z),
hostile(Z). Full stop is used to indicate the end of
any Prolog statement
Prolog (cont.)
Basis: Depth-first, left-to-right backward chaining with Horn
clauses (the program and the goal are written in Horn clauses)
Built-in predicates for arithmetic etc., e.g.,
X is Y*Z+3
Logical operators <, >, =<, >=, =:= (equal), =\= (not equal)
X =:= Y (X and Y are equal)
Built-in predicates that have side effects (e.g., input and
output )
read(N).
write(‘Hello’).
Queries in Prolog are written after a question mark ?-
?- owns(adam, book).
Prolog (cont.)
Queries in Prolog are written after a question mark ?-
for example:
?- owns(adam, book).
This query is asking Does Adam own the book?, or Is it a fact that Adam
owns the book? (If we interpret adam to be a person called Adam, and
book to be some particular book).
When a question is asked of a Prolog system, it will search through the
database. It looks for facts that unify with the fact in the question.
If Prolog finds a fact that unifies with the question, Prolog system will
respond true.
If no such fact exists in the database, Prolog system will respond false.
Prolog (cont.)
The statement p(X, 2, 2) = p (1, Y, X), succeeded if
the terms p(X, 2, 2) and p(1, Y, X) can be matched:
?- p(X, 2, 2) = p (1, Y, X).
false (Why?)
?- write(‘Hello’), nl. (nl: new line)
Prolog Example 1
Show that Socrates is mortal using the following:
Allmen are mortal.
Socrates is a man.
Using Prolog language syntax:
mortal(X):- man(X).
man(socrates).
The goal:
?- mortal(socrates).
true
Prolog Example 2 The notation
[E|L] denotes a
list whose first
Appending two lists to produce a third list: element is E and
append([ ], Y, Y). whose rest is L
Appending the empty list ([ ]) and the list Y produces Y.
append([A| X], Y , [A| Z]) :- append(X, Y, Z).
[A | Z] is the result of appending [A |]X] and Y, if Z is the result of appending X and
Y.
Prolog Example 2 The notation
[E|L] denotes a
list whose first
Appending two lists to produce a third list:
element is E and
append([ ], L, L).
whose rest is L
append([X|L1], L2, [X|L3]) :- append(L1, L2, L3).
query: ?- append(A, B, [1,2]).
There are 3 possible answers; type ;
answers: A=[ ], after each answer to display the next
B=[1,2]; answer. If there is no more answers the
A=[1],
Prolog system displays false
B=[2];
A=[1,2],
B=[ ];
false
Tracing of Example 2
?- append([1, 2], [3, 4], Z).
Z = [1, 2, 3, 4]
append([ ], L, L).
append([X|L1], L2,[X|L3]) :- append(L1, L2, L3).
θ= {X/1, L1/[2], L2/[3, 4], Z/[1|L3]}
θ
Prolog Example 2 (cont.)
?- append([1, 2], [3, 4], Z).
Z = [1, 2, 3, 4]
append([ ], L, L).
θ= {X/1, L1/[2], L2/[3, 4], Z/[1|L3]}
append([X|L1],L2,[X|L3]) :- append(L1, L2, L3).
Renaming of the 2nd rule
append([Y|L4, L5, [Y|L6]):- append(L4, L5, L6]). append([Y|L4, L5, [Y|L6])
θ1 = {Y/2, L4/[ ], L5/[3, 4], L3/[2, L6]}
L6])
θ2={L6/[3, 4]}
Tracing of Example 2 (cont.)
θ2={L6/[3, 4]}
θ1 = {Y/2, L4/[ ], L5/[3, 4], L3/[2, L6]}
θ= {X/1, L1/[2], L2/[3, 4], Z/[1|L3]}
L6 = [3, 4]
L3 = [2| L6]
= [2, 3, 4]
Z = [ 1 |L3]
= [1, 2, 3, 4]
Prolog Example 3
owns(nono, m1).
missile(m1).
american(west).
enemy(nono, america).
criminal(X) :- american(X), weapon(Y), sells(X, Y, Z), hostile(Z).
sells(west, X, nono) :- missile(X), owns(nono, X).
hostile(X) :- enemy(X, america).
weapon(X) :- missile(X).
Prolog Example 3
FOL Prolog
American(x) Weapon(y) Sells(x,y,z) Hostile(z) criminal(X) :- american(X), weapon(Y), sells(X, Y, Z), hostile(Z).
Criminal(x)
owns(nono, m1).
Owns(Nono,M1) and Missile(M1 ) missile(m1 ).
Missile(x) Owns(Nono,x) Sells(West,x,Nono) sells(west,X,nono):- missile(X) , owns(nono,X).
Missile(x) Weapon(x)
weapon(X) :- missile(X).
hostile(x) :- enemy(X, america) .
Enemy(x,America) Hostile(x)
american(west).
American(West) enemy(nono,america).
Enemy(Nono,America)
Example 4
% size of a list
size([ ], 0).
size([H|T], N) :- size(T, N1), N is N1 +1.
?- size ([1, 2, 3, 4], N).
N=4
Example 5
% reversing a list
reverse ([ ], X, X).
reverse ([X| Y], Z, W) :- reverse (Y, [X|Z], W).
?-
| reverse([1, 2, 3], [ ], A).
A = [3, 2, 1].
Example 6
factorial(0, 1). ? factorial (3, W).
W=6
factorial(N, F):- ? factorial (4, 24).
true
N > 0,
N1 is N-1,
factorial(N1, F1),
F is N *F1.
Negation as Failure
Negation as Failure: Prolog assumes that a literal L is proven
if it is unable to prove ¬L.
Example:
unmarriedStudent(X):- not(married(X)), student(X).
student(mona).
married(sally).
• not(married(mona)) is true since married(mona)
cannot be proved.
• student(sally) is not true; therefore
unmarriedStudent(X) is not true
H. W.
Determine, in which of the following lists cases the unification
succeeds and where it fails? If it succeeds, write down the unifier.
(Note: Uppercase are variables.)
1. [a, d, z, c] and [H|T ]
2. [apple, pear, grape] and [A, pear|Rest]
3. [a|Rest] and [a, b, c]
4. [one] and [Two]
H. W.
Determine, in which of the following lists cases the unification succeeds and
where it fails? If it succeeds, write down the unifier. (Note: Uppercase are
variables.)
1. [a, d, z, c] and [H|T ]
{H/ a, T /[d, z, c]}
2. [apple, pear, grape] and [A, pear|Rest]
{A/apple, Rest/[grape]}
3. [a|Rest] and [a, b, c]
{Rest/[b, c]}
4. [one] and [Two]
{Two/one}
H. W.
Write Prolog predicates ismember(X, List), to check
whether X is a member of a List:
?- ismember(2, [1, 2, 4, 6]).
true
H. W.
Write a Prolog predicates ismember(X, List), that
checks whether X is a member of a List:
?- ismember(2, [1, 2, 4, 6]).
true
ismember(X, [X|R]).
ismember(X, [Y|R]) :- ismember(X, R).