Introduction To Prolog11111
Introduction To Prolog11111
Prolog―Introduction Prolog
Prolog as the name itself suggests, is the short form of LOGical PROgramming. It is a
logical and declarative programming language. Before diving deep into the concepts of
Prolog, let us first understand what exactly logical programming is.
Logic Programming is one of the Computer Programming Paradigm, in which the program
statements express the facts and rules about different problems within a system of
formal logic. Here, the rules are written in the form of logical clauses, where head and
body are present. For example, H is head and B1, B2, B3 are the elements of the body.
Now if we state that “H is true, when B1, B2, B3 all are true”, this is a rule. On the other
hand,facts are like the rules, but without any body. So, an example of factis “H is true”.
Some logic programming languages like Datalog or ASP (Answer Set Programming) are
known as purely declarative languages. These languages allow statements about what
the program should accomplish. There is no such step-by-step instruction on how to
perform the task. However, other languages like Prolog, have declarative and also
imperative properties. This may also include procedural statements like “To solve the
problem H, perform B1, B2 and B3”.
1
Prolog
From this illustration, we can see that in Functional Programming, we have to define the
procedures, and the rule how the procedures work. These procedures work step by step
to solve one specific problem based on the algorithm. On the other hand, for the Logic
Programming, we will provide knowledge base. Using this knowledge base, the machine
can find answers to the given questions, which is totally different from functional
programming.
In functional programming, we have to mention how one problem can be solved, but in
logic programming we have to specify for which problem we actually want the solution.
Then the logic programming automatically finds a suitable solution that will help us solve
that specific problem.
Functional Programming follows the Von- Logic Programming uses abstract model,
Neumann Architecture, or uses the or deals with objects and their
sequential steps. relationships.
The syntax is actually the sequence of The syntax is basically the logic formulae
statements like (a, s, I). (Horn Clauses).
Logic and controls are mixed together. Logics and controls can be separated.
2
Prolog
What is Prolog?
Prolog orPROgramming inLOGics is a logical and declarative programming language. It
is one major example of the fourth generation language that supports the declarative
programming paradigm. This is particularly suitable for programs that involvesymbolic
ornon-numeric computation. This is the main reason to use Prolog as the programming
language inArtificial Intelligence, wheresymbol manipulationandinference
manipulationare the fundamental tasks.
In Prolog, we need not mention the way how one problem can be solved, we just need to
mention what the problem is, so that Prolog automatically solves it. However, in Prolog
we are supposed to give clues as thesolution method.
Facts: The fact is predicate that is true, for example, if we say,“Tom is the son of Jack”,
then this is a fact.
Rules: Rules are extinctions of facts that contain conditional clauses. To satisfy a rule
these conditions should be met. For example, if we define a rule as:
This implies that forXto be the grandfather ofY, Z should be a parent of Y and X should
be father of Z.
Questions: And to run a prolog program, we need some questions, and those questions
can be answered by the given facts and rules.
History of Prolog
The heritage of prolog includes the research on theorem provers and some other
automated deduction system that were developed in 1960s and 1970s. The Inference
mechanism of the Prolog is based on Robinson’s Resolution Principle, that was proposed
in 1965, and Answer extracting mechanism by Green (1968). These ideas came together
forcefully with the advent of linear resolution procedures.
The explicit goal-directed linear resolution procedures, gave impetus to the development
of a general purpose logic programming system. ThefirstProlog was theMarseille
Prologbased on the work byColmerauerin the year 1970. The manual of this Marseille
Prolog interpreter (Roussel, 1975) was the first detailed description of the Prolog language.
3
Prolog
• Specification Language
• Machine Learning
• Robot Planning
• Automation System
• Problem Solving
4
2. Prolog—Environment Setup
Prolog
Prolog Version
In this tutorial, we are using GNU Prolog, Version: 1.4.5
Official Website
This is the official GNU Prolog website where we can see all the necessary details about
GNU Prolog, and also get the download link.
http://www.gprolog.org/
Installation Guide
• Download the exe file and run it.
• You will see the window as shown below, then click onnext:
5
Prolog
Select properdirectorywhere you want to install the software, otherwise let it be installed
on the default directory. Then click onnext.
6
Prolog
You can verify the below screen, andcheck/uncheckappropriate boxes, otherwise you
can leave it as default. Then click onnext.
In the next step, you will see the below screen, then click onInstall.
7
Prolog
8
Prolog
9
3. Prolog—Hello World
Prolog
In the previous section, we have seen how to install GNU Prolog. Now, we will see how to
write a simpleHello Worldprogram in our Prolog environment.
write('Hello World').
Note: After each line, you have to use one period (.) symbol to show that the line has
ended.
Now let us see how to run the Prolog script file (extension is *.pl) into the Prolog console.
Before running *.pl file, we must store the file into the directory where the GNU prolog
console is pointing, otherwise just change the directory by the following steps:
Step 1: From the prolog console, go to File > Change Dir, then click on that menu.
10
Prolog
Now we can see in the prolog console, it shows that we have successfully changed the
directory.
Step 3:Now create one file (extension is *.pl) and write the code as follows:
Now let’s run the code. To run it, we have to write the file name as follows:
[hello_world]
11
Prolog
12
4. Prolog—Basics
Prolog
In this chapter, we will gain some basic knowledge about Prolog. So we will move on to
the first step of our Prolog Programming.
Knowledge Base: This is one of the fundamental parts of Logic Programming. We will
see in detail about the Knowledge Base, and how it helps in logic programming.
Facts, Rules and Queries: These are the building blocks of logic programming. We will
get some detailed knowledge about facts and rules, and also see some kind of queries
that will be used in logic programming.
Here, we will discuss about the essential building blocks of logic programming. These
building blocks areFacts, Rules and the Queries.
Facts
We can define fact as an explicit relationship between objects, and properties these objects
might have. So facts are unconditionally true in nature. Suppose we have some facts as
given below:
• Tom is a cat
• Kunal loves to eat Pasta
• Hair is black
• Nawaz loves to play games
• Pratyusha is lazy.
So these are some facts, that are unconditionally true. These are actually statements,
that we have to consider as true.
Syntax
The syntax for facts is as follows:
13
Prolog
relation(object1,object2...).
Example
cat(tom).
loves_to_eat(kunal,past
a). of_color(hair,black).
loves_to_play_games(nawa
z). lazy(pratyusha).
Rules
We can define rule as an implicit relationship between objects. So facts are conditionally
true. So when one associated condition is true, then the predicate is also true. Suppose
we have some rules as given below:
• Lili is happy if she dances.
• Tom is hungry if he is searching for food.
• Jack and Bili are friends if both of them love to play cricket.
• Ryan will go to play if school is closed, and he is free.
So these are some rules that areconditionallytrue, so when the right hand side is true,
then the left hand side is also true.
Here the symbol ( :-) will be pronounced as “If”, or “is implied by”. This is also known as
neck symbol, the LHS of this symbol is called the Head, and right hand side is called
Body. Here we can use comma (,) which is known as conjunction, and we can also use
semicolon, that is known as disjunction.
Syntax
Suppose a clause is
like : P :- Q;R.
This can also be written
as P :- Q.
P :- R.
If one clause is
like : P :-
Q,R;S,T,U.
14
Prolog
P :- (Q,R);(S,T,U).
Or can also be written
as: P :- Q,R.
P :- S,T,U.
Example
happy(lili) :- dances(lili).
hungry(tom) :-
search_for_food(tom).
friends(jack, bili) :- lovesCricket(jack),
lovesCricket(bili). goToPlay(ryan) :- isClosed(school),
Queries
Queries are some questions on the relationships between objects and object properties.
So question can be anything, as given below:
• Is tom a cat?
• Does Kunal love to eat pasta?
• Is Lili happy?
• Will Ryan go to play?
So according to these queries, Logic programming language can find the answer and return
them.
Now, we will see how to write some knowledge bases. Suppose we have our very first
knowledge base called KB1. Here in the KB1, we have some facts. The facts are used to
state things, that are unconditionally true of the domain of interest.
Knowledge Base 1
Suppose we have some knowledge, that Priya, Tiyasha, and Jaya are three girls, among
them, Priya can cook. Let’s try towrite these facts in a more generic way as shown below:
girl(priya).
girl(tiyasha).
girl(jaya).
can_cook(priya).
15
Prolog
Note: Here we have written the name in lowercase letters, because in Prolog, a string
starting with uppercase letter indicates avariable.
Now we can use this knowledge base by posingsome queries. “Is priya a girl?”, it will
reply “yes”, “is jamini a girl?” then it will answer “No”, because it does not knowwho
jamini is. Ournext question is “Can Priyacook?”, it will say “yes”, but if we ask the same
question for Jaya, it will say “No”.
Output
yes
| ?- [kb1]
.
compiling D:/TP Prolog/Sample_Codes/kb1.pl for byte code...
D:/TP Prolog/Sample_Codes/kb1.pl compiled, 3 lines read - 489 bytes
written, 10 ms
yes
| ?- girl(priya)
.
yes
| ?- girl(jamini).
no
| ?- can_cook(priya).
yes
| ?- can_cook(jaya).
no
| ?-
Knowledge Base 2
16
Prolog
Let us see another knowledge base, where we have some rules. Rules contain some
information that are conditionally true about the domain of interest. Suppose our
knowledge base is as follows:
sing_a_song(ananya
).
listens_to_music(rohit
).
listens_to_music(ananya) :-
sing_a_song(ananya). happy(ananya) :-
sing_a_song(ananya). happy(rohit) :-
So there are some facts and rules given above. The first two are facts, but the rest are
rules. As we know that Ananya sings a song, this implies she also listens to music. So if
we ask “DoesAnanya listen to music?”, the answer will be true. Similarly,“isRohit
happy?”, this will also be true because he listens to music. But if our question is “does
Ananya play guitar?”, then according to the knowledge base, it will say “No”. So these
are some examples of queries based on this Knowledge base.
Output
| ?- [kb2].
compiling D:/TP Prolog/Sample_Codes/kb2.pl for byte code...
D:/TP Prolog/Sample_Codes/kb2.pl compiled, 6 lines read - 1066 bytes
written,
15 ms
yes
| ?- happy(rohit).
yes
| ?- sing_a_song(rohit).
no
| ?- sing_a_song(ananya).
yes
| ?- playes_guitar(rohit).
yes
| ?- playes_guitar(ananya).
no
17
Prolog
| ?- listens_to_music(ananya).
yes
| ?-
Knowledge Base 3
The facts and rules of Knowledge Base 3 are as follows:
can_cook(priya).
can_cook(jaya).
can_cook(tiyasha).
likes(priya,jaya) :- can_cook(jaya).
likes(priya,tiyasha) :-
can_cook(tiyasha).
Suppose we want to see the members who can cook, we can use onevariablein our
query. The variables should start with uppercase letters. In the result, it will show one by
one. If we press enter, then it will come out, otherwise if we press semicolon (;), then it
will show the next result.
Output
| ?- [kb3].
compiling D:/TP Prolog/Sample_Codes/kb3.pl for byte code...
D:/TP Prolog/Sample_Codes/kb3.pl compiled, 5 lines read - 737 bytes
written, 22 ms
warning: D:/TP Prolog/Sample_Codes/kb3.pl:1: redefining procedure
can_cook/1 D:/TP Prolog/Sample_Codes/kb1.pl:4: previous definition
yes
| ?- can_cook(X).
X = priya ? ;
X = jaya ? ;
X = tiyasha
yes
18
Prolog
| ?- likes(priya,X).
X = jaya ? ;
X = tiyasha
yes
| ?-
19
5. Prolog—Relations
Prolog
Relationship is one of the main features that we have to properly mention in Prolog.
These relationships can be expressed as facts and rules. After that we will see about the
family relationships, how we can express family based relationships in Prolog, and also
see the recursive relationships of the family.
We will create the knowledge base by creating facts and rules, and play query on them.
Relations in Prolog
In Prolog programs, it specifies relationship between objects and properties of the
declaring the
ownership relationship between two objects—one is Amit and the other is bike.
If we ask a question,“Does Amit own a bike?”, we are actually trying to find out about
one relationship.
There are various kinds of relationships, of which some can be rules as well. A rule can
find out about a relationship even if the relationship is not defined explicitly as a fact.
These clauses can give us the answer that piyus and raj are brothers, but we will get
three pairs of output here. They are: (piyus, piyus), (piyus, raj), (raj, raj). For these pairs,
given conditions are true, but for the pairs (piyus, piyus), (raj, raj), they are not actually
brothers, they are the same persons. So we have to create the clauses properly to form a
relationship.
20
Prolog
Here from this tree, we can understand that there are few relationships. Here bob is a
child of pam and tom, and bob also has two children—ann and pat. Bob has one brother
liz, whose parent is also tom. So we want to make predicates as follows:
21
Prolog
Predicates
• parent(pam, bob).
• parent(tom, bob).
• parent(tom, liz).
• parent(bob, ann).
• parent(bob, pat).
• parent(pat, jim).
• parent(bob, peter).
• parent(peter, jim).
• The user can easily query the Prolog system about relations defined in the program.
• The arguments of relations can (among other things) be: concrete objects, or
constants (such as pat and jim), or general objects such as X and Y. Objects of the
first kind in our program are called atoms. Objects of the second kind are called
variables.
22
Prolog
Now if we want to make mother and sister relationship, then we can write as given below:
female(pa).
female(liz.
female(pat.
female(an).
male(jim).
male(bob).
male(tom).
male(peter.
parent(pam,bob).
parent(tom,bob).
parent(tom,liz).
parent(bob,ann).
parent(bob,pat).
parent(pat,jim).
parent(bob,peter).
parent(peter,jim).
23
Prolog
mother(X,Y):- parent(X,Y),female(X).
father(X,Y):-
parent(X,Y),male(X).
haschild(X):- parent(X,_).
sister(X,Y):- parent(Z,X),parent(Z,Y),female(X),X\==Y.
brother(X,Y):-parent(Z,X),parent(Z,Y),male(X),X\==Y.
Output
| ?- [family].
compiling D:/TP Prolog/Sample_Codes/family.pl for byte code...
D:/TP Prolog/Sample_Codes/family.pl compiled, 23 lines read - 3088 bytes
written, 9 ms
yes
| ?- parent(X,jim).
X = pat ? ;
X = peter
yes
| ?-
mother(X,Y)
.
X = pam
Y = bob ? ;
X = pat
Y = jim ? ;
no
| ?- haschild(X).
X = pam ? ;
X = tom ? ;
24
Prolog
X = tom ? ;
X = bob ? ;
X = bob ? ;
X = pat ? ;
X = bob ? ;
X = peter
yes
| ?- sister(X,Y).
X = liz
Y = bob ? ;
X = ann
Y = pat ? ;
X = ann
Y = peter ? ;
X = pat
Y = ann ? ;
X = pat
Y = peter ? ;
(16 ms) no
| ?-
Now let us see some more relationships that we can make from the previous
relationships of a family. So if we want to make a grandparent relationship, that can be
formed as follows:
25
Prolog
We can also create some other relationships like wife, uncle, etc. We can write the
relationships as given below:
• grandparent(X,Y) :- parent(X,Z), parent(Z,Y).
• grandmother(X,Z) :- mother(X,Y), parent(Y,Z).
• grandfather(X,Z) :- father(X,Y), parent(Y,Z).
• wife(X,Y) :- parent(X,Z),parent(Y,Z), female(X),male(Y).
• uncle(X,Z) :- brother(X,Y), parent(Y,Z).
So let us write a prolog program to see this in action. Here we will also see the trace to
trace-out the execution.
female(pam
).
female(liz)
.
female(pat)
.
female(ann
).
male(jim).
male(bob).
male(tom).
male(peter)
.
Prolog
parent(bob,pat)
.
parent(pat,jim).
parent(bob,peter
).
parent(peter,jim)
.
mother(X,Y):- parent(X,Y),female(X).
father(X,Y):-parent(X,Y),male(X).
sister(X,Y):-parent(Z,X),parent(Z,Y),female(X),X\==Y.
brother(X,Y):-parent(Z,X),parent(Z,Y),male(X),X\==Y.
grandparent(X,Y):-parent(X,Z),parent(Z,Y).
grandmother(X,Z):-mother(X,Y),parent(Y,Z).
grandfather(X,Z):-father(X,Y),parent(Y,Z).
Output
| ?- [family_ext].
compiling D:/TP Prolog/Sample_Codes/family_ext.pl for byte code...
D:/TP Prolog/Sample_Codes/family_ext.pl compiled, 27 lines read - 4646
bytes written, 10 ms
| ?- uncle(X,Y).
X = peter
Y = jim ? ;
no
| ?- grandparent(X,Y).
X = pam
Y = ann ? ;
X = pam
Y = pat ? ;
X = pam
Y = peter ? ;
27
Prolog
X = tom
Y = ann ? ;
X = tom
Y = pat ? ;
X = tom
Y = peter ? ;
X = bob
Y = jim ? ;
X = bob
Y = jim ? ;
no
| ?- wife(X,Y).
X = pam
Y = tom ? ;
X = pat
Y = peter ? ;
(15 ms) no
| ?-
28
Prolog
Program
| ?- [family_ext].
compiling D:/TP Prolog/Sample_Codes/family_ext.pl for byte code...
D:/TP Prolog/Sample_Codes/family_ext.pl compiled, 27 lines read - 4646
bytes written, 10 ms
X = pam
Y = bob ? ;
X = pat
Y = jim ? ;
no
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- mother(pam,Y).
11 Call: mother(pam,_23) ?
22 Call: parent(pam,_23) ?
22 Exit: parent(pam,bob) ?
32 Call: female(pam) ?
32 Exit: female(pam) ?
11 Exit: mother(pam,bob) ?
Y = bob
(16 ms)
29
Prolog
{trace}
| ?- notrace.
The debugger is switched off
yes
| ?-
30
Prolog
female(pam
).
female(liz)
.
female(pat)
.
female(ann
).
male(jim).
male(bob).
male(tom).
male(peter)
.
31
Prolog
parent(bob,pat)
.
parent(pat,jim).
parent(bob,peter
).
parent(peter,jim)
.
Output
| ?- [family_rec].
yes
| ?- predecessor(peter,X).
X = jim ? ;
no
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
1 1 Call: predecessor(bob,_2 ?
| ?- predecessor(bob,X).
3)
2 2 Call: parent(bob,_23) ?
2 2 Exit: parent(bob,ann) ?
1 1 Exit: predecessor(bob,an ?
n)
X = ann ? ;
11Redo: predecessor(bob,ann) ?
2 2Redo: parent(bob,ann) ?
32
Prolog
2 2 Exit: parent(bob,pat) ?
1 1 Exit: predecessor(bob,pat) ?
X = pat ? ;
1 1 Redo: predecessor(bob,pat) ?
2 2 Redo: parent(bob,pat) ?
2 2 Exit: parent(bob,peter) ?
1 1 Exit: predecessor(bob,peter) ?
X = pet ?
er ;
1 1 Redo: predecessor(bob,peter) ?
2 2 Call: parent(bob,_92) ?
2 2 Exit: parent(bob,ann) ?
3 2 Call: predecessor(ann,_23) ?
4 3 Call: parent(ann,_23) ?
4 3 Fail: parent(ann,_23) ?
4 3 Call: parent(ann,_141) ?
4 3 Fail: parent(ann,_129) ?
3 2 Fail: predecessor(ann,_23) ?
2 2 Redo: parent(bob,ann) ?
2 2 Exit: parent(bob,pat) ?
3 2 Call: predecessor(pat,_23) ?
4 3 Call: parent(pat,_23) ?
4 3 Exit: parent(pat,jim) ?
3 2 Exit: predecessor(pat,jim) ?
1 1 Exit: predecessor(bob,jim) ?
X = jim ? ;
1 1 Redo: predecessor(bob,jim) ?
3 2 Redo: predecessor(pat,jim) ?
4 3 Call: parent(pat,_141) ?
4 3 Exit: parent(pat,jim) ?
5 3 Call: predecessor(jim,_23) ?
33
Prolog
6 4 Call: parent(jim,_23) ?
6 4 Fail: parent(jim,_23) ?
6 4 Call: parent(jim,_190) ?
6 4 Fail: parent(jim,_178) ?
5 3 Fail: predecessor(jim,_23)
?
3 2 Fail: predecessor(pat,_23)
?
2 2 Redo: parent(bob,pat) ?
2 2 Exit: parent(bob,peter) ?
3 2 Call: predecessor(peter,_2 ?
3)
4 3 Call: parent(peter,_23) ?
4 3 Exit: parent(peter,jim) ?
3 2 Exit: predecessor(peter,ji ?
m)
1 1 Exit: predecessor(bob,jim)
?
X = jim ?
{trace}
| ?-
34
6. Prolog—Data Objects Prolog
In this chapter, we will learn data objects in Prolog. They can be divided into few different
categories as shown below:
35
Prolog
Atoms
Atoms are one variation of constants. They can be any names or objects. There are few
rules that should be followed when we are trying to use Atoms as given below:
Strings of letters, digits and the underscore character, ‘_', starting with a lower-
case letter.For example:
• azahar
• b59
• b_59
• b_59AB
• b_x25
• antara_sarkar
We have to keep in mind that when using atoms of this form, some care is necessary as
some strings of special characters already have a predefined meaning; for example ':-'.
• <--->
=======>
• ...
• .:.
• ::=
This is useful if we want to have an atom that starts with a capital letter. By enclosing it
in quotes, we make it distinguishable from variables:
• ‘Rubai'
• ‘Arindam_Chatterjee'
• ‘Sumit Mitra'
Numbers
Another variation of constants is the Numbers. So integer numbers can be represented
as 100, 4, -81, 1202. In Prolog, the normal range of integers is from -16383 to 16383.
Prolog also supports real numbers, but normally the use-case of floating point number is
very less in Prolog programs, because Prolog is for symbolic, non-numeric computation.
The treatment of real numbers depends on the implementation of Prolog. Example of
real numbers are 3.14159, -0.00062, 450.18, etc.
Variables
36
Prolog
The variables come under theSimple Objectssection. Variables can be used in many
such cases in our Prolog program, that we have seen earlier. So there are some rules of
defining variables in Prolog.
We can define Prolog variables, such that variables are strings of letters, digits and
underscore characters. Theystart withanupper-case letteror anunderscore
character. Some examples of Variables are:
•X
• Sum
• Memer_name
• Student_list
• Shoppinglist
• _a50
• _15
Now the question is, where should we use these anonymous variables?
Suppose in our knowledge base we have some facts— “jim hates tom”, “pat hates bob”.
So if tom wants to find out who hates him, then he can use variables. However, if he
wants to check whether there is someone who hates him, we can use anonymous
variables. So when we want to use the variable, but do not want to reveal the value of
the variable, then we can use anonymous variables.
hates(jim,tom).
hates(pat,bob).
hates(dog,fox).
hates(peter,tom
).
Output
| ?- [var_anonymous].
compiling D:/TP Prolog/Sample_Codes/var_anonymous.pl for byte code...
D:/TP Prolog/Sample_Codes/var_anonymous.pl compiled, 3 lines read - 536
bytes written, 16 ms
yes
| ?- hates(X,tom).
37
Prolog
X = jim ? ;
X = peter
yes
| ?- hates(_,tom).
true ? ;
no
| ?- hates(_,fox).
true ? ;
no
| ?-
38
7.Prolog—Operators
Prolog
In the following sections, we will see what are the different types of operators in Prolog.
Types of the comparison operators and Arithmetic operators.
We will also see how these are different from any other high level language operators,
how they are syntactically different, and how they are different in their work. Also we will
see some practical demonstration to understand the usage of different operators.
Comparison Operators
Comparison operators are used to compare two equations or states. Following are different
comparison operators:
Operator Meaning
You can see that the ‘=<’ operator, ‘=:=’ operator and ‘=\=’ operators are syntactically
different from other languages. Let us see some practical demonstration to this.
Example
| ?- 1+2=:=2+1.
yes
| ?- 1+2=2+1.
no
| ?- 1+A=B+2.
A = 2
B = 1
yes
39
Prolog
| ?- 5<10.
yes
| ?- 5>10.
no
| ?- 10=\=100.
yes
Here we can see 1+2=:=2+1 is returning true, but 1+2=2+1 is returning false. This is
because, in the first case it is checking whether the value of 1 + 2 is same as 2 + 1 or
not, and the otherone is checking whether two patterns ‘1+2’ and ‘2+1’ are same or not.
As they are not same, it returns no (false). In the case of 1+A=B+2, A and B are two
variables, and they are automatically assigned to some values that will match the
pattern.
Operator Meaning
+ Addition
- Subtraction
* Multiplication
/ Division
** Power
// Integer Division
mod Modulus
Let us see one practical code to understand the usage of these operators.
Program
A 10 / 30,write('100 / 30 is
is 0 '),write(A),nl,
B 10 // 30,write('100 // 30 is
is 0 '),write(B),nl,
C 10 ** 2,write('100 ** 2 is
is 0 '),write(C),nl,
40
Prolog
Output
| ?- change_directory('D:/TP Prolog/Sample_Codes').
yes
| ?- [op_arith].
compiling D:/TP Prolog/Sample_Codes/op_arith.pl for byte code...
D:/TP Prolog/Sample_Codes/op_arith.pl compiled, 6 lines read - 2390 bytes
written, 11 ms
yes
| ?- calc.
100 + 200 is 300
400 - 150 is 250
10 * 300 is 3000
100 / 30 is 3.3333333333333335
100 // 30 is 3
100 ** 2 is 10000.0
100 mod 30 is 10
yes
| ?-
41
8. Prolog—Loop & Decision
Prolog
Making
Loops
Loop statements are used to execute the code block multiple times. In general, for,
while, do-while are loop constructs in programming languages (like Java, C, C++).
Code block is executed multiple times using recursive predicate logic. There are no direct
loops in some other languages, but we can simulate loops with few different techniques.
Program
count_to_10(10) :-
write(10),nl.
count_to_10(X) :-
write(X),nl
, Y is X +
1,
count_to_10(Y).
Output
42
| ?- [loop].
compiling D:/TP Prolog/Sample_Codes/loop.pl for byte code...
D:/TP Prolog/Sample_Codes/loop.pl compiled, 4 lines read - 751 bytes
written,
16 ms
true ?
43
Prolog
yes
| ?-
Now create a loop that takes lowest and highest values. So, we can use the between() to
simulate loops.
Program
count_down(L, H) :-
between(L, H,
Y), Z is H - Y,
write(Z), nl.
count_up(L, H) :-
between(L, H,
Y), Z is L + Y,
write(Z), nl.
Output
| ?- [loop].
compiling D:/TP Prolog/Sample_Codes/loop.pl for byte code...
D:/TP Prolog/Sample_Codes/loop.pl compiled, 14 lines read - 1700 bytes
written,
16 ms
yes
| ?-
count_down(12,17). 5
true ?
; 4
true ?
; 3
true ?
; 2
true ? ;
44
Prolog
true ?
; 0
yes
| ?-
count_up(5,12).
10
true ?
; 11
true ?
; 12
true ?
; 13
true ?
; 14
true ?
; 15
true ?
; 16
true ?
; 17
yes
| ?-
45
Prolog
Decision Making
The decision statements are If-Then-Else statements. So when we try to match some
condition, and perform some task, then we use the decision making statements. The
basic usage is as follows:
In some different programming languages, there are If-Else statements, but in Prolog we
have to define our statements in some other manner. Following is an example of decision
making in Prolog.
Program
% If-Then-Else statement
% If-Elif-Else statement
Output
| ?- [test].
compiling D:/TP Prolog/Sample_Codes/test.pl for byte code...
D:/TP Prolog/Sample_Codes/test.pl compiled, 3 lines read - 529 bytes
written,
15 ms
yes
| ?- gt(10,100).
X is smaller
yes
| ?- gt(150,100).
X is greater or equal
true ?
yes
46
Prolog
| ?- gte(10,20).
X is smaller
true ?
yes
| ?- gte(100,100).
X and Y are same
true ?
yes
| ?-
47
9. Prolog—Conjunctions &
Prolog
Disjunctions
In this chapter, we shall discuss Conjunction and Disjunction properties. These properties
are used in other programming languages using AND and OR logics. Prolog also uses the
same logic in its syntax.
Conjunction
Conjunction (AND logic) can be implemented using the comma (,) operator. So two
predicates separated by comma are joined with AND statement. Suppose we have a
predicate,parent(jhon, bob), which means“Jhon is parent of Bob”, and another
predicate,male(jhon), which means“Jhon is male”. So we can make another predicate
thatfather(jhon,bob), which means“Jhon is father of Bob”. We can define predicate
father, when he is parentANDhe is male.
Disjunction
Disjunction (OR logic) can be implemented using the semi-colon (;) operator. So two
predicates separated by semi-colon are joined with OR statement. Suppose we have a
predicate,father(jhon, bob). This tells that“Jhon is father of Bob”, and another
predicate,mother(lili,bob), this tells that“lili is mother of bob”. If we create another
predicate aschild(), this will be true whenfather(jhon, bob)is trueOR mother(lili,bob)is
true.
Program
parent(jhon,bob
).
parent(lili,bob)
.
male(jhon).
female(lili)
.
% Conjunction Logic
father(X,Y) :- parent(X,Y),male(X).
mother(X,Y) :- parent(X,Y),female(X).
Output
| ?- [conj_disj].
48
compiling D:/TP Prolog/Sample_Codes/conj_disj.pl for byte code...
Prolog
yes
| ?- father(jhon,bob).
yes
| ?- child_of(jhon,bob).
true ?
yes
| ?- child_of(lili,bob).
yes
| ?-
49
10. Prolog—Lists
Prolog
In this chapter, we will discuss one of the important concepts in Prolog, The Lists. It is a
data structure that can be used in different cases for non-numeric programming. Lists
are used to store the atoms as a collection.
Representation of Lists
The list is a simple data structure that is widely used in non-numeric programming. List
consists of any number of items, for example, red, green, blue, white, dark. It will be
represented as, [red, green, blue, white, dark]. The list of elements will be enclosed with
square brackets.
A list can be eitheremptyornon-empty. In the first case, the list is simply written as a
Prolog atom, []. In the second case, the list consists of two things as given below:
• The first item, called theheadof the list;
• The remaining part of the list, called thetail.
Suppose we have a list like: [red, green, blue, white, dark]. Here the head is red and tail
is [green, blue, white, dark]. So the tail is another list.
Now, let us consider we have a list, L = [a, b, c]. If we write Tail = [b, c] then we can also
write the list L as L = [ a | Tail]. Here the vertical bar (|) separates the head and tail parts.
A data structure that is either empty or consists of two parts: a head and a tail. The tail
itself has to be a list.
41
0
Prolog
Operations Definition
Membership Operation
During this operation, we can check whether a member X is present in list L or not? So
how to check this? Well, we have to define one predicate to do so. Suppose the predicate
name islist_member(X,L). The goal of this predicate is to check whether X is present in L
or not.
Program
list_member(X,[X|_]).
list_member(X,[_|TAIL]) :- list_member(X,TAIL).
Output
| ?- [list_basics].
compiling D:/TP Prolog/Sample_Codes/list_basics.pl for byte code...
D:/TP Prolog/Sample_Codes/list_basics.pl compiled, 1 lines read - 467
bytes written, 13 ms
yes
50
Prolog
| ?- list_member(b,[a,b,c]).
true ?
yes
| ?- list_member(b,[a,[b,c]]).
no
| ?- list_member([b,c],[a,[b,c]]).
true ?
yes
| ?- list_member(d,[a,b,c]).
no
| ?- list_member(d,[a,b,c]).
Length Calculation
This is used to find the length of list L. We will define one predicate to do this task. Suppose
the predicate name islist_length(L,N). This takes L and N as input argument. This will
count the elements in a list L and instantiate N to their number. As was the case with our
previous relations involving lists, it is useful to consider two cases:
• If list is empty, then length is 0.
• If the list is not empty, then L = [Head|Tail], then its length is 1 + length of Tail.
Program
list_length([],0).
list_length([_|TAIL],N) :- list_length(TAIL,N1), N is N1 + 1.
Output
| ?- [list_basics].
compiling D:/TP Prolog/Sample_Codes/list_basics.pl for byte code...
D:/TP Prolog/Sample_Codes/list_basics.pl compiled, 4 lines read - 985
bytes written, 23 ms
yes
| ?- list_length([a,b,c,d,e,f,g,h,i,j],Len).
51
Prolog
Len = 10
yes
| ?- list_length([],Len).
Len = 0
yes
| ?- list_length([[a,b],[c,d],[e,f]],Len).
Len = 3
yes
| ?-
Concatenation
Concatenation of two lists means adding the list items of the second list after the first
one. So if two lists are [a,b,c] and [1,2], then the final list will be [a,b,c,1,2]. So to do this
task we will create one predicate called list_concat(), that will take first list L1, second list
L2, and the L3 as resultant list. There are two observations here.
• If the first list is empty, and second list is L, then the resultant list will be L.
• If the first list is not empty, then write this as [Head|Tail], concatenate Tail with L2
recursively, and store into new list in the form, [Head|New List].
Program
list_concat([],L,L).
list_concat([X1|L1],L2,[X1|L3])
| ?- [list_basics]. :- list_concat(L1,L2,L3).
yes
| ?- list_concat([1,2],[a,b,c],NewList).
Output
52
Prolog
NewList = [1,2,a,b,c]
yes
| ?- list_concat([],[a,b,c],NewList).
NewList = [a,b,c]
yes
| ?- list_concat([[1,2,3],[p,q,r]],[a,b,c],NewList).
NewList = [[1,2,3],[p,q,r],a,b,c]
yes
| ?-
Program
| ?- [list_basics].
compiling D:/TP Prolog/Sample_Codes/list_basics.pl for byte code...
D:/TP Prolog/Sample_Codes/list_basics.pl compiled, 11 lines read - 1923
bytes written, 25 ms
yes
| ?- list_delete(a,[a,e,i,o,u],NewList).
53
Prolog
NewList = [e,i,o,u] ?
yes
| ?- list_delete(a,[a],NewList).
NewList = [] ?
yes
| ?- list_delete(X,[a,e,i,o,u],[a,e,o,u]).
X = i ? ;
no
| ?-
Program
list_member(X,[X|_]).
list_member(X,[_|TAIL]) :- list_member(X,TAIL).
list_append(A,T,T) :-
list_member(A,T),!. list_append(A,T,[A|
T]).
In this case, we have used (!) symbol, that is known as cut. So when the first line is
executed successfully, then we cut it, so it will not execute the next operation.
Output
| ?- [list_basics].
compiling D:/TP Prolog/Sample_Codes/list_basics.pl for byte code...
D:/TP Prolog/Sample_Codes/list_basics.pl compiled, 14 lines read - 2334
bytes written, 25 ms
(16 ms)
yes 54
Prolog
| ?- list_append(a,[e,i,o,u],NewList).
NewList = [a,e,i,o,u]
yes
| ?- list_append(e,[e,i,o,u],NewList).
NewList = [e,i,o,u]
yes
| ?- list_append([a,b],[e,i,o,u],NewList).
NewList = [[a,b],e,i,o,u]
yes
| ?-
Program
Output
| ?- [list_basics].
compiling D:/TP Prolog/Sample_Codes/list_basics.pl for byte code...
D:/TP Prolog/Sample_Codes/list_basics.pl compiled, 16 lines read - 2558
bytes written, 22 ms
(16 ms)
yes 55
Prolog
| ?- list_insert(a,[e,i,o,u],NewList).
NewList = [a,e,i,o,u] ? a
NewList = [e,a,i,o,u]
NewList = [e,i,a,o,u]
NewList = [e,i,o,a,u]
NewList = [e,i,o,u,a]
NewList = [e,i,o,u,a]
(15 ms) no
| ?-
Permutation Operation
This operation will change the list item positions and generate all possible outcomes. So
we will create one predicate as list_perm(L1,L2), This will generate all permutation of L1,
and store them into L2. To do this we need list_delete() clause to help.
X is member of L if either:
56
Prolog
• If the first list is empty, then the second list must also be empty.
• If the first list is not empty then it has the form [X | L], and a permutation of such
a list can be constructed as, first permute L obtaining L1 and then insert X at any
position into L1.
Program
list_delete(X,[X|L1], L1).
list_delete(X, [Y|L2], [Y|L1]) :- list_delete(X,L2,L1).
list_perm([],[]).
list_perm(L,[X|P]) :- list_delete(X,L,L1),list_perm(L1,P).
Output
| ?- [list_repos].
compiling D:/TP Prolog/Sample_Codes/list_repos.pl for byte code...
D:/TP Prolog/Sample_Codes/list_repos.pl compiled, 4 lines read - 1060
bytes written, 17 ms
X = [a,b,c,d] ? a
X = [a,b,d,c]
X = [a,c,b,d]
X = [a,c,d,b]
X = [a,d,b,c]
X = [a,d,c,b]
X = [b,a,c,d]
X = [b,a,d,c]
X = [b,c,a,d]
57
Prolog
X = [b,c,d,a]
X = [b,d,a,c]
X = [b,d,c,a]
X = [c,a,b,d]
X = [c,a,d,b]
X = [c,b,a,d]
X = [c,b,d,a]
X = [c,d,a,b]
X = [c,d,b,a]
X = [d,a,b,c]
X = [d,a,c,b]
X = [d,b,a,c]
X = [d,b,c,a]
X = [d,c,a,b]
X = [d,c,b,a]
(31 ms) no
| ?-
58
Prolog
Reverse Operation
Suppose we have a list L = [a,b,c,d,e], and we want to reverse the elements, so the output
will be [e,d,c,b,a]. To do this, we will create a clause, list_reverse(List, ReversedList).
Following are some observations:
• If the list is empty, then the resultant list will also be empty.
• Otherwise put the list items namely, [Head|Tail], and reverse the Tail items
recursively, and concatenate with the Head.
• This can also be used to check whether two lists are reverse of each other or not.
Program
list_concat([],L,L).
list_concat([X1|L1],L2,[X1|L3]) :- list_concat(L1,L2,L3).
list_rev([],[]). list_rev([Head|
Tail],Reversed) :-
list_rev(Tail, RevTail),list_concat(RevTail, [Head],Reversed).
Output
| ?- [list_repos].
compiling D:/TP Prolog/Sample_Codes/list_repos.pl for byte code...
D:/TP Prolog/Sample_Codes/list_repos.pl compiled, 10 lines read - 1977
bytes written, 19 ms
yes
| ?- list_rev([a,b,c,d,e],NewList).
NewList = [e,d,c,b,a]
yes
| ?- list_rev([a,b,c,d,e],[e,d,c,b,a]).
yes
| ?-
Shift Operation
Using Shift operation, we can shift one element of a list to the left rotationally. So if the
list items are [a,b,c,d], then after shifting, it will be [b,c,d,a]. So we will make a clause
list_shift(L1, L2).
59
Prolog
• We will express the list as [Head|Tail], then recursively concatenate Head after
the Tail, so as a result we can feel that the elements are shifted.
• This can also be used to check whether the two lists are shifted at one position or
not.
Program
list_concat([],L,L).
list_concat([X1|L1],L2,[X1|L3]) :- list_concat(L1,L2,L3).
Output
| ?- [list_repos].
compiling D:/TP Prolog/Sample_Codes/list_repos.pl for byte code...
D:/TP Prolog/Sample_Codes/list_repos.pl compiled, 12 lines read - 2287
bytes written, 10 ms
yes
| ?- list_shift([a,b,c,d,e],L2).
L2 = [b,c,d,e,a]
yes
| ?-
Order Operation
Here we will define a predicate list_order(L) which checks whether L is ordered or not. So
if L = [1,2,3,4,5,6], then the result will be true.
• If there is only one element, that is already ordered.
• Otherwise take first two elements X and Y as Head, and rest as Tail. If X =< Y,
then call the clause again with the parameter [Y|Tail], so this will recursively
check from the next element.
Program
list_order([X]).
Prolog
Output
| ?- [list_repos].
compiling D:/TP Prolog/Sample_Codes/list_repos.pl for byte code...
D:/TP Prolog/Sample_Codes/list_repos.pl:15: warning: singleton
variables [X] for list_order/1
D:/TP Prolog/Sample_Codes/list_repos.pl compiled, 15 lines read - 2805
bytes written, 18 ms
yes
| ?- list_order([1,2,3,4,5,6,6,7,7,8]).
true ?
yes
| ?- list_order([1,4,2,3,6,5]).
no
| ?-
61
Prolog
Program
list_subset([],[]).
list_subset([Head|Tail],[Head|Subset]) :- list_subset(Tail,Subset).
list_subset([Head|Tail],Subset) :- list_subset(Tail,Subset).
Output
| ?- [list_set].
compiling D:/TP Prolog/Sample_Codes/list_set.pl for byte code...
D:/TP Prolog/Sample_Codes/list_set.pl:3: warning: singleton variables
[Head] for list_subset/2
D:/TP Prolog/Sample_Codes/list_set.pl compiled, 2 lines read - 653 bytes
written, 7 ms
yes
| ?- list_subset([a,b],X).
X = [a,b] ? ;
X = [a] ? ;
X = [b] ? ;
X = []
X = [x,y,z] ? a
X = [x,y]
X = [x,z]
X = [x]
X = [y,z]
62
Prolog
X = [y]
X = [z]
X = []
yes
| ?-
Union Operation
Let us define a clause called list_union(L1,L2,L3), So this will take L1 and L2, and perform
Union on them, and store the result into L3. As you know if two lists have the same element
twice, then after union, there will be only one. So we need another helper clause to
check the membership.
Program
list_member(X,[X|_]).
list_member(X,[_|TAIL]) :- list_member(X,TAIL).
Note: In the program, we have used (\+) operator, this operator is used forNOT.
Output
| ?- [list_set].
compiling D:/TP Prolog/Sample_Codes/list_set.pl for byte code...
D:/TP Prolog/Sample_Codes/list_set.pl:6: warning: singleton variables
[Head] for list_subset/2
D:/TP Prolog/Sample_Codes/list_set.pl compiled, 9 lines read - 2004 bytes
written, 18 ms
yes
| ?- list_union([a,b,c,d,e],[a,e,i,o,u],L3).
L3 = [b,c,d,a,e,i,o,u] ?
63
Prolog
| ?- list_union([a,b,c,d,e],[1,2],L3).
L3 = [a,b,c,d,e,1,2]
yes
Intersection Operation
Let us define a clause called list_intersection(L1,L2,L3), So this will take L1 and L2, and
perform Intersection operation, and store the result into L3. Intersection will return those
elements that are present in both lists. So L1 = [a,b,c,d,e], L2 = [a,e,i,o,u], then L3 =
[a,e]. Here, we will use the list_member() clause to check if one element is present in a
list or not.
Program
list_member(X,[X|_]).
list_member(X,[_|TAIL]) :- list_member(X,TAIL).
list_intersect([X|Y],Z,[X|W]) :-
list_member(X,Z), list_intersect(Y,Z,W).
list_intersect([X|Y],Z,W) :-
\+ list_member(X,Z),
list_intersect(Y,Z,W). list_intersect([],Z,
[]).
Output
| ?- [list_set].
compiling D:/TP Prolog/Sample_Codes/list_set.pl for byte code...
D:/TP Prolog/Sample_Codes/list_set.pl compiled, 13 lines read - 3054 bytes
written, 9 ms
L3 = [a,e] ?
yes
| ?- list_intersect([a,b,c,d,e],[],L3).
L3 = []
64
Prolog
yes
| ?-
Even and Odd Length Finding Verifies whether the list has odd number
or even number of elements.
Program
list_even_len([]).
list_even_len([Head|Tail]) :- list_odd_len(Tail).
list_odd_len([_]).
65
Prolog
list_odd_len([Head|Tail]) :- list_even_len(Tail).
Output
| ?- [list_misc].
compiling D:/TP Prolog/Sample_Codes/list_misc.pl for byte code...
D:/TP Prolog/Sample_Codes/list_misc.pl:2: warning: singleton variables
[Head] for list_even_len/1
D:/TP Prolog/Sample_Codes/list_misc.pl:5: warning: singleton variables
[Head] for list_odd_len/1
D:/TP Prolog/Sample_Codes/list_misc.pl compiled, 4 lines read - 726 bytes
written, 20 ms
yes
| ?- list_odd_len([a,2,b,3,c]).
true ?
yes
| ?- list_odd_len([a,2,b,3]).
no
| ?- list_even_len([a,2,b,3]).
true ?
yes
| ?- list_even_len([a,2,b,3,c]).
no
| ?-
66
Prolog
• If there is only one element, then the first list will be a list with that element, and
the second list will be empty.
• Suppose X,Y are two elements from head, and rest are Tail, So make two lists
[X|List1], [Y|List2], these List1 and List2 are separated by dividing Tail.
Program
list_divide([],[],[]).
list_divide([X],[X],[]). list_divide([X,Y|
Tail], [X|List1],[Y|List2]) :-
list_divide(Tail,List1,List2).
Output
| ?- [list_misc].
compiling D:/TP Prolog/Sample_Codes/list_misc.pl for byte code...
D:/TP Prolog/Sample_Codes/list_misc.pl:2: warning: singleton variables
[Head] for list_even_len/1
D:/TP Prolog/Sample_Codes/list_misc.pl:5: warning: singleton variables
[Head] for list_odd_len/1
D:/TP Prolog/Sample_Codes/list_misc.pl compiled, 8 lines read - 1432 bytes
written, 8 ms
yes
| ?- list_divide([a,1,b,2,c,3,d,5,e],L1,L2).
L1 = [a,b,c,d,e]
L2 = [1,2,3,5] ?
yes
| ?- list_divide([a,b,c,d],L1,L2).
L1 = [a,c]
L2 = [b,d]
yes
| ?-
67
Prolog
Program
max_of_two(X,Y,X) :- X >=
Y. max_of_two(X,Y,Y) :- X
< Y.
list_max_elem([X],X).
list_max_elem([X,Y|Rest],Max)
:-
list_max_elem([Y|
Rest],MaxRest),
max_of_two(X,MaxRest,Max).
Output
| ?- [list_misc].
compiling D:/TP Prolog/Sample_Codes/list_misc.pl for byte code...
D:/TP Prolog/Sample_Codes/list_misc.pl:2: warning: singleton variables
[Head] for list_even_len/1
D:/TP Prolog/Sample_Codes/list_misc.pl:5: warning: singleton variables
[Head] for list_odd_len/1
D:/TP Prolog/Sample_Codes/list_misc.pl compiled, 16 lines read - 2385
bytes written, 16 ms
yes
| ?- list_max_elem([8,5,3,4,7,9,6,1],Max).
Max = 9 ?
yes
| ?- list_max_elem([5,12,69,112,48,4],Max).
Max = 112 ?
68
yes
| ?-
Prolog
Program
list_sum([],0).
list_sum([Head|Tail], Sum)
:-
list_sum(Tail,SumTemp
), Sum is Head +
Output
yes
| ?- [list_misc].
compiling D:/TP Prolog/Sample_Codes/list_misc.pl for byte code...
D:/TP Prolog/Sample_Codes/list_misc.pl:2: warning: singleton variables
[Head] for list_even_len/1
D:/TP Prolog/Sample_Codes/list_misc.pl:5: warning: singleton variables
[Head] for list_odd_len/1
D:/TP Prolog/Sample_Codes/list_misc.pl compiled, 21 lines read - 2897
bytes written, 21 ms
Sum = 250
yes
| ?- list_sum([8,5,3,4,7,9,6,1],Sum).
Sum = 43
yes
| ?-
69
Prolog
We will define a predicate called mergesort(L, SL), it will take L and return result into SL.
Program
split([],[],[]).
split([A],[A],[]).
split([A,B|R],[A|Ra],[B|Rb])
:- split(R,Ra,Rb).
merge(A,[],A).
merge([],B,B). merge([A|
Ra],[B|Rb],[A|M]) :-
A =< B, merge(Ra,[B|
Rb],M). merge([A|Ra],[B|
Rb],[B|M]) :-
A > B, merge([A|Ra],Rb,M).
Output
| ?- [merge_sort].
compiling D:/TP Prolog/Sample_Codes/merge_sort.pl for byte code...
D:/TP Prolog/Sample_Codes/merge_sort.pl compiled, 17 lines read - 3048
bytes written, 19 ms
70
yes
Prolog
| ?- mergesort([4,5,3,7,8,1,2],L).
L = [1,2,3,4,5,7,8] ?
yes
| ?- mergesort([8,5,3,4,7,9,6,1],L).
L = [1,3,4,5,6,7,8,9] ?
yes
| ?-
71