Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 19

WHAT IS PROLOG PROGRAMMING LANGUAGE?

Prolog (programming logic) rose within the realm of Artificial Intelligence. It


was one of the first logic programming languages. It became popular with AI
researchers, who know more about “what” and “how” intelligent behaviour is
achieved. The idea behind it deals with the logical and declarative aspects.
This language represents a fundamentally new approach to computing and
became a serious competitor to LISP. Following are the developers of
PROLOG

WRITE AN SAMPLE PROGRAM IN PROLOG LANGUAGE?


Here is an example. of Sample programming language by displaying the
message “Hello”:
SOURCE CODE
// the main program (this is a comment)
Hello:-
nl,
write(‘Hello !’ ).
}

HOW BACKTRACKING IN PROLOG IS DONE?


BACKTRACKING IS DONE AS FOLLOWS IN PROLOG:
example:
Who does ROBIN teach?
?- lectures(ROBIN, Course), studies(Student, Course).
Course = 9311
Student = jack ;
Course = 9314
Student = jill ;
Course = 9314
Student = henry ;
Prolog solves this problem by proceeding left to right and then backtracking.
When given the initial query, Prolog starts by trying to solve
lectures(ROBIN, Course).
There are six lectures clauses, but only two have ROBIN as their first
argument.
Prolog uses the first clause that refers to ROBIN: lectures(ROBIN, 9311).
With Course = 9311, it tries to satisfy the next goal, studies(Student, 9311).
It finds the fact studies(jack, 9311). and hence the first solution: (Course =
9311, Student = jack).

GIVE AN EXAMPLE OF USING STRUCTURES IN


PROLOG?
Functional terms can be used to construct complex data structures.Here is
the example. of using structure in PROLOG:
 How do we ask, “What books does John own that were written by someone
called LeGuin”?
?- owns(john, book(Title, author(leguin, GivenName))).
Title = 'Tehanu'
GivenName = ursula
 What books does John own?
?- owns(john, Book).
Book = book('Tehanu', author(leguin, ursula))
 What books does John own?
?- owns(john, book(Title, Author)).
Title = 'Tehanu'
Author = author(leguin, ursula)
 Prolog performs a complex matching operation between the structures in
the query and those in the clause head.
HOW VARIABLES ARE USED IN PROLOG?
HERE IS AN EXAMPLE:
Suppose we want to ask, “What course does ROBIN teach”?,then we can
write it in prolog as
” Is there a course,x,that ROBIN teaches? “
HERE,
here x stands for an object that the questioner does not know about yet,so
to answer the prolog has to find the value of x.If we know the value of
variable then it is known as BOUND, if we don’t know then known as
UNBOUND.

NAME SOME DATA TYPES IN PROLOG PROGRAMMING


LANGUAGE?

FOLLOWING ARE THE DATA TYPES SUPPORTED BY PROLOG :Prolog’s single


data type is the term. Terms are
either atoms, numbers, variables or compound terms.

 ATOM : An atom is a general-purpose name with no inherent meaning.

 NUMBERS : Numbers are like integers,float etc.

 VARIABLES : Are denoted string consisting of letters, numbers,


underscore characters, and beginning with an upper-case letter or
underscore.

 COMPOUND TERMS : A compound term is composed of an atom called


a “functor” and a number of “arguments”, which are again terms. They are
written by separating them by commas.
WHY WE USE PROLOG PROGRAMMING LANGUAGE?
FOLLOWING ARE SOME POINTS FOR USING PROLOG MORE:
 SWI-Prolog is free, open-source, and very well maintained.
 It’s much much easier to distribute SWI-Prolog applications than Java ones
 Prolog is much less verbose,which is helpful when during development.
 Prolog allows one to define any word or collection of “symbol characters”
(e.g. >>, +, /, , //, :===/===: ) as an infix, postfix, or prefix operator.
 In Prolog, you can treat data as programs.
 Prolog is interactive.

NAME THE AREAS IN WHICH PROLOG PROGRAMMING


LANGUAGE IS USED?
Following are some areas in which prolog is used:
 intelligent data base retrieval

 natural language understanding

 expert systems

 specification language

 machine learning

 robot planning

 automated reasoning

 problem solving

WHAT ARE THE FEATURES OF PROLOG LANGUAGE?


FOLLOWING ARE THE FEATURES OF PROLOG LANGUAGE:
 Intelligent Systems – programs which perform useful tasks by utilizing
artificial intelligence techniques.
 Expert Systems – intelligent systems which reproduce decision-making
at the level of a human expert.
 Natural Language Systems – which can analysis and respond to
statements made in ordinary language as opposed to approved keywords
or menu selections.
Programming in Prolog
In Prolog, loading code is referred to as consulting. Prolog can be used interactively
by entering queries at the Prolog prompt ?- . If there is no solution, Prolog writes no .
If a solution exists then it is printed. If there are multiple solutions to the query, then
these can be requested by entering a semi-colon ; . There are guidelines on good
programming practice to improve code efficiency, readability and maintainability. [18]
Here follow some example programs written in Prolog.
Hello World
An example of a query:

?- write('Hello World!'), nl.


Hello World!
true.

?-

Compiler optimization
Any computation can be expressed declaratively as a sequence of state transitions.
As an example, an optimizing compiler with three optimization passes could be
implemented as a relation between an initial program and its optimized form:

program_optimized(Prog0, Prog) :-
optimization_pass_1(Prog0, Prog1),
optimization_pass_2(Prog1, Prog2),
optimization_pass_3(Prog2, Prog).

or equivalently using DCG notation:

program_optimized --> optimization_pass_1, optimization_pass_2,


optimization_pass_3.

Quicksort
The quicksort sorting algorithm, relating a list to its sorted version:

partition([], _, [], []).


partition([X|Xs], Pivot, Smalls, Bigs) :-
( X @< Pivot ->
Smalls = [X|Rest],
partition(Xs, Pivot, Rest, Bigs)
; Bigs = [X|Rest],
partition(Xs, Pivot, Smalls, Rest)
).
quicksort([]) --> [].
quicksort([X|Xs]) -->
{ partition(Xs, X, Smaller, Bigger) },
quicksort(Smaller), [X], quicksort(Bigger).

Syntax and Basic Fields :

In prolog, We declare some facts. These facts constitute the Knowledge Base
of the system. We can query against the Knowledge Base. We get output as
affirmative if our query is already in the knowledge Base or it is implied by
Knowledge Base, otherwise we get output as negative. So, Knowledge Base
can be considered similar to database, against which we can query. Prolog
facts are expressed in definite pattern. Facts contain entities and their
relation. Entities are written within the parenthesis separated by comma (, ).
Their relation is expressed at the start and outside the parenthesis. Every
fact/rule ends with a dot (.). So, a typical prolog fact goes as follows :

Format : relation(entity1, entity2, ....k'th entity).

Example :
friends(raju, mahesh).
singer(sonu).
odd_number(5).

Explanation :
These facts can be interpreted as :
raju and mahesh are friends.
sonu is a singer.
5 is an odd number.
Key Features :
1. Unification : The basic idea is, can the given terms be made to represent the
same structure.
2. Backtracking : When a task fails, prolog traces backwards and tries to satisfy
previous task.
3. Recursion : Recursion is the basis for any search in program.
Running queries :
A typical prolog query can be asked as :
Query 1 : ?- singer(sonu).
Output : Yes.

Explanation : As our knowledge base contains


the above fact, so output was 'Yes', otherwise
it would have been 'No'.

Query 2 : ?- odd_number(7).
Output : No.

Explanation : As our knowledge base does not


contain the above fact, so output was 'No'.

https://www.albany.edu/~csi311/sample.Prolog.questions.html

Symbolic Computation
A good example of symbolic computation and its problems is symbolic differentiation.
Below is given a set of basic rules of differentiation in a PROLOG format.

deriv(C,X,0) :- constant(C).

deriv(X,X,1) :- !.

deriv(-F,X,-G) :- deriv(F,X,G).

deriv(F+G,X,H+I) :- deriv(F,X,H), deriv(G,X,I).


deriv(F*G,X,H*G+F*I) :- deriv(F,X,H), deriv(G,X,I).

deriv(F^C,X,c*F^(C-1)*G) :- const(C), deriv(F,X,G).

deriv(F/G,X,H/G - (F/G^2)*I) :- deriv(F,X,H), deriv(G,X,I).

deriv(log(F),X,H*(F^(-1)) :- deriv(F,X,H).

Higher-order programming
A higher-order predicate is a predicate that takes one or more other predicates as
arguments. Although support for higher-order programming takes Prolog outside the
domain of first-order logic, which does not allow quantification over
predicates,[25] ISO Prolog now has some built-in higher-order predicates such
as call/1 , call/2 , call/3 , findall/3 , setof/3 , and bagof/3 .[26] Furthermore, since
arbitrary Prolog goals can be constructed and evaluated at run-time, it is easy to
write higher-order predicates like maplist/2 , which applies an arbitrary predicate to
each member of a given list, and sublist/3 , which filters elements that satisfy a
given predicate, also allowing for currying.[24]
To convert solutions from temporal representation (answer substitutions on
backtracking) to spatial representation (terms), Prolog has various all-solutions
predicates that collect all answer substitutions of a given query in a list. This can be
used for list comprehension. For example, perfect numbers equal the sum of their
proper divisors:

perfect(N) :-
between(1, inf, N), U is N // 2,
findall(D, (between(1,U,D), N mod D =:= 0), Ds),
sumlist(Ds, N).

This can be used to enumerate perfect numbers, and also to check whether a
number is perfect.
As another example, the predicate maplist applies a predicate P to all
corresponding positions in a pair of lists:
maplist(_, [], []).
maplist(P, [X|Xs], [Y|Ys]) :-
call(P, X, Y),
maplist(P, Xs, Ys).

When P is a predicate that for all X , P(X,Y) unifies Y with a single unique
value, maplist(P, Xs, Ys) is equivalent to applying the map function in functional
programming as Ys = map(Function, Xs) .
Higher-order programming style in Prolog was pioneered in HiLog and λProlog.

Meta-interpreters and reflection


Prolog is a homoiconic language and provides many facilities for reflection. Its
implicit execution strategy makes it possible to write a concise meta-circular
evaluator (also called meta-interpreter) for pure Prolog code:

solve(true).
solve((Subgoal1,Subgoal2)) :-
solve(Subgoal1),
solve(Subgoal2).
solve(Head) :-
clause(Head, Body),
solve(Body).

where true represents an empty conjunction, and clause(Head, Body) unifies with
clauses in the database of the form Head :- Body .
Since Prolog programs are themselves sequences of Prolog terms ( :-/2 is an
infix operator) that are easily read and inspected using built-in mechanisms
(like read/1 ), it is possible to write customized interpreters that augment Prolog with
domain-specific features. For example, Sterling and Shapiro present a meta-
interpreter that performs reasoning with uncertainty, reproduced here with slight
modifications:[29]:330

solve(true, 1) :- !.
solve((Subgoal1,Subgoal2), Certainty) :-
!,
solve(Subgoal1, Certainty1),
solve(Subgoal2, Certainty2),
Certainty is min(Certainty1, Certainty2).
solve(Goal, 1) :-
builtin(Goal), !,
Goal.
solve(Head, Certainty) :-
clause_cf(Head, Body, Certainty1),
solve(Body, Certainty2),
Certainty is Certainty1 * Certainty2.

This interpreter uses a table of built-in Prolog predicates of the form[29]:327

builtin(A is B).
builtin(read(X)).
% etc.

and clauses represented as clause_cf(Head, Body, Certainty) . Given those, it can


be called as solve(Goal, Certainty) to execute Goal and obtain a measure of
certainty about the result.

Turing completeness
Pure Prolog is based on a subset of first-order predicate logic, Horn clauses, which
is Turing-complete. Turing completeness of Prolog can be shown by using it to
simulate a Turing machine:

turing(Tape0, Tape) :-
perform(q0, [], Ls, Tape0, Rs),
reverse(Ls, Ls1),
append(Ls1, Rs, Tape).

perform(qf, Ls, Ls, Rs, Rs) :- !.


perform(Q0, Ls0, Ls, Rs0, Rs) :-
symbol(Rs0, Sym, RsRest),
once(rule(Q0, Sym, Q1, NewSym, Action)),
action(Action, Ls0, Ls1, [NewSym|RsRest], Rs1),
perform(Q1, Ls1, Ls, Rs1, Rs).

symbol([], b, []).
symbol([Sym|Rs], Sym, Rs).

action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs).


action(stay, Ls, Ls, Rs, Rs).
action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs).

left([], [], Rs0, [b|Rs0]).


left([L|Ls], Ls, Rs, [L|Rs]).

A simple example Turing machine is specified by the facts:

rule(q0, 1, q0, 1, right).


rule(q0, b, qf, 1, stay).
This machine performs incrementation by one of a number in unary encoding: It
loops over any number of "1" cells and appends an additional "1" at the end.
Example query and result:

?- turing([1,1,1], Ts).
Ts = [1, 1, 1, 1] ;

This illustrates how any computation can be expressed declaratively as a sequence


of state transitions, implemented in Prolog as a relation between successive states
of interest.

History
The name Prolog was chosen by Philippe Roussel as an abbreviation
for programmation en logique (French for programming in logic). It was created
around 1972 by Alain Colmerauer with Philippe Roussel, based on Robert
Kowalski's procedural interpretation of Horn clauses. It was motivated in part by the
desire to reconcile the use of logic as a declarative knowledge representation
language with the procedural representation of knowledge that was popular in North
America in the late 1960s and early 1970s. According to Robert Kowalski, the first
Prolog system was developed in 1972 by Colmerauer and Phillipe Roussel.[5] The
first implementation of Prolog was an interpreter written in Fortran by Gerard Battani
and Henri Meloni. David H. D. Warren took this interpreter to Edinburgh, and there
implemented an alternative front-end, which came to define the “Edinburgh Prolog”
syntax used by most modern implementations. Warren also implemented the first
compiler for Prolog, creating the influential DEC-10 Prolog in collaboration with
Fernando Pereira. Warren later generalised the ideas behind DEC-10 Prolog, to
create the Warren Abstract Machine.
European AI researchers favored Prolog while Americans favored Lisp, reportedly
causing many nationalistic debates on the merits of the languages. Much of the
modern development of Prolog came from the impetus of the Fifth Generation
Computer Systems project (FGCS), which developed a variant of Prolog
named Kernel Language for its first operating system.
Pure Prolog was originally restricted to the use of a resolution theorem prover with Horn
clauses of the form:

H :- B1, ..., Bn.

The application of the theorem-prover treats such clauses as procedures:

to show/solve H, show/solve B1 and ... and Bn.


Pure Prolog was soon extended, however, to include negation as failure, in which
negative conditions of the form not(Bi) are shown by trying and failing to solve the
corresponding positive conditions Bi.
Subsequent extensions of Prolog by the original team introduced constraint logic
programming abilities into the implementations.

Variables in prolog

 Suppose we want to ask, "What course does Turing teach"?


 This could be written as:
 Is there a course, X, that Turing teaches?
 The variable X stands for an object that the questioner does not know about
yet.
 To answer the question, Prolog has to find out the value of X, if it exists.
 As long as we do not know the value of a variable it is said to be unbound.
 When a value is found, the variable is said to bound to that value.
 The name of a variable must begin with a capital letter or an underscore
character, "_".

Variables 2

 To ask Prolog to find the course that Turing teaches, enter this:
?- lectures(turing, Course).
Course = 9020 ← output from Prolog

 To ask which course(s) Prof. Codd teaches, we may ask,


?- lectures(codd , Course).
Course = 9311 ; ← type ";" to get next solution
Course = 9314
?-

If Prolog can tell that there are no more solutions, it just gives you the ?- prompt for a
new query, as here. If Prolog can't tell, it will let you type ; again, and then if there is no
further solution, report false.

 Prolog can find all possible ways to answer a query, unless you explicitly tell it
not to (see cut, later).
Backtracking in Prolog

 Who does Codd teach?


?- lectures(codd, Course), studies(Student, Course).
Course = 9311
Student = jack ;

Course = 9314
Student = jill ;

Course = 9314
Student = henry ;

 Prolog solves this problem by proceeding left to right and then backtracking.
 When given the initial query, Prolog starts by trying to solve
lectures(codd, Course)

 There are six lectures clauses, but only two have codd as their first argument.
 Prolog uses the first clause that refers to codd: lectures(codd, 9311).
 With Course = 9311, it tries to satisfy the next goal, studies(Student, 9311).
 It finds the fact studies(jack, 9311). and hence the first solution: (Course =
9311, Student = jack)

Backtracking in Prolog 2

 After the first solution is found, Prolog retraces its steps up the tree and looks
for alternative solutions.
 First it looks for other students studying 9311 (but finds none).
 Then it
o backs up
o rebinds Course to 9314,
o goes down the lectures(codd, 9314) branch
o tries studies(Student, 9314),
o finds the other two solutions:
(Course = 9314, Student = jill)
and (Course = 9314, Student = henry).
Backtracking in Prolog 3

To picture what happens when Prolog tries to find a solution and backtracks, we draw a "proof
tree":

Another cut example in prolog

 max, without cut:


% max(A, B, C) binds C to the larger of A and B.
max(A, B, A) :-
A > B.
max(A, B, B) :-
A =< B.

max, with cut:


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

 The first version has a negated test in the second rule (=< vs >). The second
version substitutes a cut in the first rule for the negated test.
 Remember, no cuts in the first assignment unless they are essential! Hint: the
first assignment can be done without cuts.
Another cut example 2

remove_dups, without cut:


remove_dups([], []).
remove_dups([First | Rest], NewRest) :-
member(First, Rest),
remove_dups(Rest, NewRest).
remove_dups([First | Rest], [First | NewRest]) :-
not(member(First, Rest)),
remove_dups(Rest, NewRest).

remove_dups, with cut:


remove_dups([], []).
remove_dups([First | Rest], NewRest) :-
member(First, Rest),
!,
remove_dups(Rest, NewRest).
remove_dups([First | Rest], [First | NewRest]) :-
remove_dups(Rest, NewRest).

 The first version has a negated test in the third rule (not(member(First,
Rest))). The second version substitutes a cut in the second rule for the
negated test in the third rule.

Here are some simple clauses.


likes(mary,food).
likes(mary,wine).
likes(john,wine).
likes(john,mary).

The following queries yield the specified answers.

| ?- likes(mary,food).
yes.
| ?- likes(john,wine).
yes.
| ?- likes(john,food).
no.

How do you add the following facts?

1. John likes anything that Mary likes


2. John likes anyone who likes wine
3. John likes anyone who likes themselves
Recursion: Towers of Hanoi
The 3-disk setup is like this:

| | |
xxx | |
xxxxx | |
xxxxxxx | |
_________________________________

Here's a sample:

% move(N,X,Y,Z) - move N disks from peg X to peg Y, with peg Z being the
% auxilliary peg
%
% Strategy:
% Base Case: One disc - To transfer a stack consisting of 1 disc from
% peg X to peg Y, simply move that disc from X to Y
% Recursive Case: To transfer n discs from X to Y, do the following:
Transfer the first n-1 discs to some other peg X
Move the last disc on X to Y
Transfer the n-1 discs from X to peg Y

move(1,X,Y,_) :-
write('Move top disk from '),
write(X),
write(' to '),
write(Y),
nl.
move(N,X,Y,Z) :-
N>1,
M is N-1,
move(M,X,Z,Y),
move(1,X,Y,_),
move(M,Z,Y,X).

- note the use of "anonymous" variables _

Here is what happens when Prolog solves the case N=3.

?- move(3,left,right,center).
Move top disk from left to right
Move top disk from left to center
Move top disk from right to center
Move top disk from left to right
Move top disk from center to left
Move top disk from center to right
Move top disk from left to right

yes
An prolog example using lists:
(a) length of a list

size([],0).
size([H|T],N) :- size(T,N1), N is N1+1.
% or size([_|T],N) :- size(T,N1), N is N1+1.

| ?- size([1,2,3,4],N).

N = 4

yes
| ?- size([bill,ted,ming,pascal,nat,ron],N).

N = 6

yes
| ?- size([a, [b, c, d], e, [f | g], h], N).

N = 5

yes

(b) summing elements of a list of numbers

sumlist([],0).
ssumlist([H|T],N) :- sumlist(T,N1), N is N1+H.

(c) list membership

member(X,[X|_]).
member(X,[_|T]) :- member(X,T).

(d) reversing a list

reverse(List, Reversed) :-
reverse(List, [], Reversed).

reverse([], Reversed, Reversed).


reverse([Head|Tail], SoFar, Reversed) :-
reverse(Tail, [Head|SoFar], Reversed).

| ?- myreverse([a,b,c,d],X).

X = [d,c,b,a]; <- note semicolon (more solns?)

no

| ?- myreverse([a,b,c,d],[d,b,c,a]).

no
| ?- myreverse([a,b,c,d],[d,c,b,a]).
yes

- note difference between reverse/2 and reverse/3


- reverse/3 probably should be called reverseHelper or
something else for clarity

Advantages of Prolog

As I said above, Prolog is not a general-purpose theorem prover. It is a programming language in


which procedures can be written as logical specifications. You have to know how it executes
predicates in order to use it profitably.

Why use Prolog rather than C?

 It has built-in list handling, very useful for representing sequences,


trees, and so on.
 It is easy to read and write programs which build structures.
add( complex(A,B), complex(C,D),
complex(E,F)
) :-
E is A+C,
F is B+D.

Most Prologs nowadays should be able to handle structures of at least


30Kbytes in size.

 Although Prolog is not a complete implementation of logic, it is much


closer to it than C, and is more like mathematical notation.
 It is easy to build tables and databases while a program is running, as I
did with memo_fib. You don't need a lot of programming effort.
What are Prolog's disadvantages?

 It tempts you to write things that look logically correct, but that won't run.
 The obvious way to write a predicate is unlikely to be efficient. You must know
when a predicate needs to be optimised.
 Because it lacks functional notation, predicates can become cumbersome.
 f( N, F ) :-
 N1 is N - 1,
 f( N1, F1 ),
F is N * F1.

It would be much nicer to write


f( N ) = N * f(N-1).

 Input and output is not always easy.


 There are some features which have not been standardised, and differ
between implementations. For example: formatted input and output, file-
handling, sorting predicates.
 You can't re-assign to parts of data structures. This makes it impossible to
implement arrays. However, functional programmers have developed a
number of fast-access data structures which do almost as good a job.

You might also like